@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
@@ -29,6 +29,7 @@ import {
29
29
  isReasoningStreamingSupported,
30
30
  getReasoningVerbosity,
31
31
  } from '../lib/multi-agent-capabilities.js';
32
+ import { req } from '../lib/requirement-ids.js';
32
33
 
33
34
  const FIXTURE = 'conformance-agent-reasoning-streaming';
34
35
  /** Expected concatenation of the fixture's `streamChunks` — kept in sync
@@ -64,14 +65,14 @@ describe.skipIf(SKIP)('agentReasoningStreaming: RFC 0024 incremental + closing e
64
65
 
65
66
  expect(
66
67
  deltas.length,
67
- driver.describe(
68
+ req('openwop.it.agentReasoningStreaming.emits-n-agent-reasoning-delta-events-followed-by-exactly-one-closing-agent-reaso',
68
69
  'RFCS/0024-agent-reasoning-streaming.md §Proposal',
69
70
  'streaming host MUST emit one agent.reasoning.delta per streamChunks entry',
70
71
  ),
71
72
  ).toBe(EXPECTED_CHUNKS.length);
72
73
  expect(
73
74
  finals.length,
74
- driver.describe(
75
+ req('openwop.it.agentReasoningStreaming.emits-n-agent-reasoning-delta-events-followed-by-exactly-one-closing-agent-reaso',
75
76
  'RFCS/0024-agent-reasoning-streaming.md §Proposal',
76
77
  'streaming host MUST emit exactly one closing agent.reasoned event after the deltas',
77
78
  ),
@@ -95,7 +96,7 @@ describe.skipIf(SKIP)('agentReasoningStreaming: RFC 0024 incremental + closing e
95
96
 
96
97
  expect(
97
98
  sequences,
98
- driver.describe(
99
+ req('openwop.it.agentReasoningStreaming.agent-reasoning-delta-sequence-starts-at-0-and-increments-by-1-within-the-block',
99
100
  'RFCS/0024-agent-reasoning-streaming.md §Proposal',
100
101
  '`sequence` MUST start at 0 and increment by 1 per delta within a block',
101
102
  ),
@@ -113,15 +114,15 @@ describe.skipIf(SKIP)('agentReasoningStreaming: RFC 0024 incremental + closing e
113
114
  const list = (events.json as { events: Array<{ type: string; payload?: Record<string, unknown> }> }).events;
114
115
 
115
116
  const finalEvent = list.find((e) => e.type === 'agent.reasoned');
116
- expect(finalEvent, 'closing agent.reasoned must be present').toBeDefined();
117
+ expect(finalEvent, req('openwop.it.agentReasoningStreaming.closing-agent-reasoned-reasoning-is-the-concatenation-of-the-deltas-authoritativ', 'RFCS/0024-agent-reasoning-streaming.md §Proposal', 'closing agent.reasoned must be present')).toBeDefined();
117
118
  const reasoning = finalEvent?.payload?.reasoning;
118
- expect(typeof reasoning, 'closing event MUST carry a reasoning string').toBe('string');
119
+ expect(typeof reasoning, req('openwop.it.agentReasoningStreaming.closing-agent-reasoned-reasoning-is-the-concatenation-of-the-deltas-authoritativ', 'RFCS/0024-agent-reasoning-streaming.md §Proposal', 'closing event MUST carry a reasoning string')).toBe('string');
119
120
  // The mock-agent's contract: closing reasoning equals concat(streamChunks).
120
121
  // Real hosts MAY transform at finalize (summary truncation, redaction);
121
122
  // for the mock-agent fixture, no transform applies — exact equality.
122
123
  expect(
123
124
  reasoning,
124
- driver.describe(
125
+ req('openwop.it.agentReasoningStreaming.closing-agent-reasoned-reasoning-is-the-concatenation-of-the-deltas-authoritativ',
125
126
  'RFCS/0024-agent-reasoning-streaming.md §Proposal',
126
127
  'closing agent.reasoned.reasoning is authoritative; for the mock-agent fixture, equals delta concatenation',
127
128
  ),
@@ -149,7 +150,7 @@ describe.skipIf(SKIP)('agentReasoningStreaming: RFC 0024 incremental + closing e
149
150
 
150
151
  expect(
151
152
  agentIds.size,
152
- driver.describe(
153
+ req('openwop.it.agentReasoningStreaming.agentid-is-consistent-across-all-streaming-closing-events-in-a-block',
153
154
  'RFCS/0024-agent-reasoning-streaming.md §Proposal',
154
155
  'agentId MUST be consistent across all `agent.reasoning.delta` events AND the closing `agent.reasoned` for a given block',
155
156
  ),
@@ -168,7 +169,7 @@ describe.skipIf(SKIP)('agentReasoningStreaming: RFC 0024 incremental + closing e
168
169
  const arr = Array.isArray(list) ? list : list.events;
169
170
 
170
171
  const closingIdx = arr.findIndex((e) => e.type === 'agent.reasoned');
171
- expect(closingIdx, 'closing event present').toBeGreaterThan(-1);
172
+ expect(closingIdx, req('openwop.it.agentReasoningStreaming.all-agent-reasoning-delta-events-arrive-before-the-closing-agent-reasoned', 'RFCS/0024-agent-reasoning-streaming.md §Proposal', 'closing event present')).toBeGreaterThan(-1);
172
173
  const lastDeltaIdx = arr.map((e) => e.type).lastIndexOf('agent.reasoning.delta');
173
174
 
174
175
  // Guard against vacuous pass: a host advertising streaming but
@@ -177,14 +178,14 @@ describe.skipIf(SKIP)('agentReasoningStreaming: RFC 0024 incremental + closing e
177
178
  // one delta MUST appear in the event log.
178
179
  expect(
179
180
  lastDeltaIdx,
180
- driver.describe(
181
+ req('openwop.it.agentReasoningStreaming.all-agent-reasoning-delta-events-arrive-before-the-closing-agent-reasoned',
181
182
  'RFCS/0024-agent-reasoning-streaming.md §Proposal',
182
183
  'streaming host MUST emit at least one `agent.reasoning.delta` for a fixture with non-empty `streamChunks`',
183
184
  ),
184
185
  ).toBeGreaterThan(-1);
185
186
  expect(
186
187
  lastDeltaIdx,
187
- driver.describe(
188
+ req('openwop.it.agentReasoningStreaming.all-agent-reasoning-delta-events-arrive-before-the-closing-agent-reasoned',
188
189
  'RFCS/0024-agent-reasoning-streaming.md §Proposal',
189
190
  'every `agent.reasoning.delta` MUST precede the closing `agent.reasoned` for the same block',
190
191
  ),
@@ -36,6 +36,8 @@ import { describe, it, expect, beforeAll } from 'vitest';
36
36
  import { existsSync } from 'node:fs';
37
37
  import { dirname, resolve } from 'node:path';
38
38
  import { fileURLToPath } from 'node:url';
39
+ import { req } from '../lib/requirement-ids.js';
40
+ import { softSkip } from '../lib/soft-skip.js';
39
41
 
40
42
  const __dirname = dirname(fileURLToPath(import.meta.url));
41
43
  const PACK_PATH = resolve(__dirname, '../../../packs/core.openwop.agents/index.mjs');
@@ -83,14 +85,14 @@ describe('category: core.openwop.agents.run — tool-allowlist enforcement (OPEN
83
85
  it('skips cleanly when pack source is not bundled', () => {
84
86
  if (!packAvailable) {
85
87
  console.warn('[agents-run-tool-allowlist] pack source not present; skipping');
86
- expect(packAvailable).toBe(false);
87
- return;
88
+ expect(packAvailable, req('openwop.it.agents-run-tool-allowlist.skips-cleanly-when-pack-source-is-not-bundled', 'threat-model-prompt-injection.md', 'skips cleanly when pack source is not bundled')).toBe(false);
89
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!packAvailable` returned early ([agents-run-tool-allowlist] pack source not present; skipping)');
88
90
  }
89
91
  expect(packAvailable).toBe(true);
90
92
  });
91
93
 
92
94
  it('rejects function-typed tool.handler (the defect path)', async () => {
93
- if (!packAvailable) return;
95
+ if (!packAvailable) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!packAvailable` returned early');
94
96
  // The 1.0.0 defect: a workflow author could supply executable JS via
95
97
  // tools[].handler and the pack would await it directly with ctx. Closed
96
98
  // in 1.0.1 — the validator throws INVALID_TOOL_DECLARATION at the run
@@ -109,7 +111,7 @@ describe('category: core.openwop.agents.run — tool-allowlist enforcement (OPEN
109
111
  });
110
112
 
111
113
  it('rejects tool declaration missing a name', async () => {
112
- if (!packAvailable) return;
114
+ if (!packAvailable) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!packAvailable` returned early');
113
115
  await expectRejection(
114
116
  () => agentRun({ config: {}, inputs: { userPrompt: 'x', tools: [{ kind: 'workflow' }] } }),
115
117
  'INVALID_TOOL_DECLARATION',
@@ -118,7 +120,7 @@ describe('category: core.openwop.agents.run — tool-allowlist enforcement (OPEN
118
120
  });
119
121
 
120
122
  it('rejects tool declaration missing a kind discriminator', async () => {
121
- if (!packAvailable) return;
123
+ if (!packAvailable) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!packAvailable` returned early');
122
124
  await expectRejection(
123
125
  () => agentRun({ config: {}, inputs: { userPrompt: 'x', tools: [{ name: 't1' }] } }),
124
126
  'INVALID_TOOL_DECLARATION',
@@ -127,7 +129,7 @@ describe('category: core.openwop.agents.run — tool-allowlist enforcement (OPEN
127
129
  });
128
130
 
129
131
  it('rejects tool-driven runs when host does not provide agentRuntime', async () => {
130
- if (!packAvailable) return;
132
+ if (!packAvailable) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!packAvailable` returned early');
131
133
  // Tool dispatch MUST go through a host-resolved runtime — the 1.0.0
132
134
  // inline-handler fallback is gone.
133
135
  await expectRejection(
@@ -141,7 +143,7 @@ describe('category: core.openwop.agents.run — tool-allowlist enforcement (OPEN
141
143
  });
142
144
 
143
145
  it('tool-less run succeeds via callAIWithTools (safe fallback preserved)', async () => {
144
- if (!packAvailable) return;
146
+ if (!packAvailable) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!packAvailable` returned early');
145
147
  let toolsSeen: unknown = 'never-called';
146
148
  const ctx: AgentRunCtx = {
147
149
  config: {},
@@ -154,11 +156,11 @@ describe('category: core.openwop.agents.run — tool-allowlist enforcement (OPEN
154
156
  const result = await agentRun(ctx);
155
157
  expect(result.outputs.result).toBe('hello back');
156
158
  expect(result.outputs.finishReason).toBe('complete');
157
- expect(toolsSeen, 'tool-less fallback MUST pass an empty tools array — no LLM-driven dispatch').toEqual([]);
159
+ expect(toolsSeen, req('openwop.it.agents-run-tool-allowlist.tool-less-run-succeeds-via-callaiwithtools-safe-fallback-preserved', 'threat-model-prompt-injection.md', 'tool-less fallback MUST pass an empty tools array — no LLM-driven dispatch')).toEqual([]);
158
160
  });
159
161
 
160
162
  it('agentRuntime.run path threads through unchanged when host provides it', async () => {
161
- if (!packAvailable) return;
163
+ if (!packAvailable) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!packAvailable` returned early');
162
164
  let receivedTools: unknown;
163
165
  const ctx: AgentRunCtx = {
164
166
  config: {},
@@ -167,15 +169,15 @@ describe('category: core.openwop.agents.run — tool-allowlist enforcement (OPEN
167
169
  tools: [{ name: 't1', kind: 'workflow', ref: 'vendor.acme.demo' }],
168
170
  },
169
171
  agentRuntime: {
170
- run: async (req: unknown) => {
171
- receivedTools = (req as { tools?: unknown[] }).tools;
172
+ run: async (reqBody: unknown) => {
173
+ receivedTools = (reqBody as { tools?: unknown[] }).tools;
172
174
  return { result: 'from-runtime', toolCalls: [{ name: 't1' }] };
173
175
  },
174
176
  },
175
177
  };
176
178
  const result = await agentRun(ctx);
177
179
  expect(result.outputs.result).toBe('from-runtime');
178
- expect(receivedTools, 'host MUST receive the validated tools array').toEqual([
180
+ expect(receivedTools, req('openwop.it.agents-run-tool-allowlist.agentruntime-run-path-threads-through-unchanged-when-host-provides-it', 'threat-model-prompt-injection.md', 'host MUST receive the validated tools array')).toEqual([
179
181
  { name: 't1', kind: 'workflow', ref: 'vendor.acme.demo' },
180
182
  ]);
181
183
  });
@@ -25,6 +25,8 @@ import { join } from 'node:path';
25
25
  import { driver } from '../lib/driver.js';
26
26
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
27
27
  import { SCHEMAS_DIR } from '../lib/paths.js';
28
+ import { req } from '../lib/requirement-ids.js';
29
+ import { softSkip } from '../lib/soft-skip.js';
28
30
 
29
31
  type DiscoveryDoc = Record<string, unknown>;
30
32
 
@@ -65,16 +67,16 @@ const HTTP_SKIP = !process.env.OPENWOP_BASE_URL;
65
67
  describe.skipIf(HTTP_SKIP)('ai-envelope-shape: advertisement contract (RFC 0021 §C)', () => {
66
68
  it('capabilities.supportedEnvelopes is an array of strings (when present)', async () => {
67
69
  const d = await readDiscovery();
68
- if (d === null) return;
70
+ if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
69
71
  const env = supportedEnvelopes(d);
70
72
  // No assertion if absent — the field is optional. When present, each entry MUST be a string.
71
73
  for (const k of env) {
72
- expect(typeof k, driver.describe('capabilities.md §supportedEnvelopes', 'each entry MUST be a string')).toBe('string');
74
+ expect(typeof k, req('openwop.it.ai-envelope-shape.capabilities-supportedenvelopes-is-an-array-of-strings-when-present', 'capabilities.md §supportedEnvelopes', 'each entry MUST be a string')).toBe('string');
73
75
  }
74
76
  // Re-affirm shape: array if present (root-first per RFC 0073).
75
77
  const advertised = capabilityFamily<unknown>(d, 'supportedEnvelopes');
76
78
  if (advertised !== undefined) {
77
- expect(Array.isArray(advertised), 'supportedEnvelopes MUST be an array').toBe(true);
79
+ expect(Array.isArray(advertised), req('openwop.it.ai-envelope-shape.capabilities-supportedenvelopes-is-an-array-of-strings-when-present', 'capabilities.md §supportedEnvelopes', 'supportedEnvelopes MUST be an array')).toBe(true);
78
80
  }
79
81
  });
80
82
  });
@@ -88,7 +90,7 @@ describe('ai-envelope-shape: schema compile (RFC 0021 §A + §B)', () => {
88
90
  it('top-level ai-envelope.schema.json compiles under Ajv2020', () => {
89
91
  const schema = load('ai-envelope.schema.json');
90
92
  const validate = ajv.compile(schema);
91
- expect(validate, 'RFC 0021 §A: ai-envelope.schema.json MUST compile').toBeTypeOf('function');
93
+ expect(validate, req('openwop.it.ai-envelope-shape.top-level-ai-envelope-schema-json-compiles-under-ajv2020', 'RFC 0021 §D', 'RFC 0021 §A: ai-envelope.schema.json MUST compile')).toBeTypeOf('function');
92
94
  });
93
95
 
94
96
  for (const kind of UNIVERSAL_KINDS) {
@@ -97,7 +99,7 @@ describe('ai-envelope-shape: schema compile (RFC 0021 §A + §B)', () => {
97
99
  const validate = ajv.compile(schema);
98
100
  expect(
99
101
  validate,
100
- `RFC 0021 §B: envelopes/${kind}.schema.json MUST compile`,
102
+ req('openwop.it.ai-envelope-shape.universal-kind-schema-envelopes-schema-json-compiles-under-ajv2020', 'RFC 0021 §D', `RFC 0021 §B: envelopes/${kind}.schema.json MUST compile`),
101
103
  ).toBeTypeOf('function');
102
104
  });
103
105
  }
@@ -124,7 +126,7 @@ describe('ai-envelope-shape: round-trip validation (RFC 0021 §A)', () => {
124
126
  },
125
127
  };
126
128
  const ok = validate(positive);
127
- expect(ok, `positive fixture MUST validate; errors: ${JSON.stringify(validate.errors)}`).toBe(true);
129
+ expect(ok, req('openwop.it.ai-envelope-shape.accepts-a-positive-aienvelope-fixture', 'RFC 0021 §D', `positive fixture MUST validate; errors: ${JSON.stringify(validate.errors)}`)).toBe(true);
128
130
  });
129
131
 
130
132
  it('rejects a negative AIEnvelope fixture missing required `meta`', () => {
@@ -137,7 +139,7 @@ describe('ai-envelope-shape: round-trip validation (RFC 0021 §A)', () => {
137
139
  // meta omitted on purpose
138
140
  };
139
141
  const ok = validate(negative);
140
- expect(ok, 'RFC 0021 §A: envelope MUST require meta block').toBe(false);
142
+ expect(ok, req('openwop.it.ai-envelope-shape.rejects-a-negative-aienvelope-fixture-missing-required-meta', 'RFC 0021 §D', 'RFC 0021 §A: envelope MUST require meta block')).toBe(false);
141
143
  });
142
144
 
143
145
  it('rejects an envelope with unknown top-level property (additionalProperties:false)', () => {
@@ -151,7 +153,7 @@ describe('ai-envelope-shape: round-trip validation (RFC 0021 §A)', () => {
151
153
  unknownTopLevel: 'should reject',
152
154
  };
153
155
  const ok = validate(negative);
154
- expect(ok, 'RFC 0021 §A: top-level additionalProperties:false MUST reject unknown fields').toBe(false);
156
+ expect(ok, req('openwop.it.ai-envelope-shape.rejects-an-envelope-with-unknown-top-level-property-additionalproperties-false', 'RFC 0021 §D', 'RFC 0021 §A: top-level additionalProperties:false MUST reject unknown fields')).toBe(false);
155
157
  });
156
158
  });
157
159
 
@@ -167,12 +169,12 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
167
169
  meta: { source: 'ai-generation', ts: '2026-05-18T10:00:00Z' },
168
170
  },
169
171
  });
170
- if (res.status === 404) return; // host doesn't expose the seam
172
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (host doesn\'t expose the seam) (seam, prior step, or fixture unavailable)'); // host doesn't expose the seam
171
173
  expect(res.status).toBe(200);
172
174
  const body = res.json as { status?: string };
173
175
  expect(
174
176
  body.status,
175
- driver.describe('RFC 0021 §A point 1-3', 'valid envelope MUST be accepted'),
177
+ req('openwop.it.ai-envelope-shape.valid-clarification-request-envelope-status-accepted', 'RFC 0021 §A point 1-3', 'valid envelope MUST be accepted'),
176
178
  ).toBe('accepted');
177
179
  });
178
180
 
@@ -187,14 +189,14 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
187
189
  // meta omitted
188
190
  },
189
191
  });
190
- if (res.status === 404) return;
192
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (seam, prior step, or fixture unavailable)');
191
193
  expect(res.status).toBe(200);
192
194
  const body = res.json as { status?: string; details?: unknown[] };
193
195
  expect(
194
196
  body.status,
195
- driver.describe('RFC 0021 §A point 1', 'envelope missing required field MUST be invalid'),
197
+ req('openwop.it.ai-envelope-shape.envelope-missing-required-meta-block-status-invalid', 'RFC 0021 §A point 1', 'envelope missing required field MUST be invalid'),
196
198
  ).toBe('invalid');
197
- expect(Array.isArray(body.details), 'invalid outcome MUST carry validation details').toBe(true);
199
+ expect(Array.isArray(body.details), req('openwop.it.ai-envelope-shape.envelope-missing-required-meta-block-status-invalid', 'RFC 0021 §A point 1', 'invalid outcome MUST carry validation details')).toBe(true);
198
200
  });
199
201
 
200
202
  it('vendor-namespaced kind not in supportedEnvelopes → status: gated', async () => {
@@ -209,14 +211,14 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
209
211
  },
210
212
  hostSupportedEnvelopes: ['vendor.acme.prd.create'], // does not include the gated kind
211
213
  });
212
- if (res.status === 404) return;
214
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (seam, prior step, or fixture unavailable)');
213
215
  expect(res.status).toBe(200);
214
216
  const body = res.json as { status?: string; allowedKinds?: string[] };
215
217
  expect(
216
218
  body.status,
217
- driver.describe('RFC 0021 §A point 2', 'unadvertised kind MUST be gated'),
219
+ req('openwop.it.ai-envelope-shape.vendor-namespaced-kind-not-in-supportedenvelopes-status-gated', 'RFC 0021 §A point 2', 'unadvertised kind MUST be gated'),
218
220
  ).toBe('gated');
219
- expect(Array.isArray(body.allowedKinds), 'gated outcome MUST list the allowed kinds').toBe(true);
221
+ expect(Array.isArray(body.allowedKinds), req('openwop.it.ai-envelope-shape.vendor-namespaced-kind-not-in-supportedenvelopes-status-gated', 'RFC 0021 §A point 2', 'gated outcome MUST list the allowed kinds')).toBe(true);
220
222
  });
221
223
 
222
224
  it('counter at cap → status: breached', async () => {
@@ -231,12 +233,12 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
231
233
  },
232
234
  counters: { envelopesPerTurn: { current: 32, cap: 32 } },
233
235
  });
234
- if (res.status === 404) return;
236
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (seam, prior step, or fixture unavailable)');
235
237
  expect(res.status).toBe(200);
236
238
  const body = res.json as { status?: string; capKind?: string };
237
239
  expect(
238
240
  body.status,
239
- driver.describe('RFC 0021 §"Universal kinds"', 'envelope at cap MUST be breached'),
241
+ req('openwop.it.ai-envelope-shape.counter-at-cap-status-breached', 'RFC 0021 §"Universal kinds"', 'envelope at cap MUST be breached'),
240
242
  ).toBe('breached');
241
243
  expect(body.capKind).toBe('envelopes');
242
244
  });
@@ -255,13 +257,13 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
255
257
  },
256
258
  runTrustBoundary: 'untrusted',
257
259
  });
258
- if (res.status === 404) return;
260
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (seam, prior step, or fixture unavailable)');
259
261
  expect(res.status).toBe(200);
260
262
  const body = res.json as { status?: string; normalizedMeta?: { contentTrust?: string } };
261
263
  expect(body.status).toBe('accepted');
262
264
  expect(
263
265
  body.normalizedMeta?.contentTrust,
264
- driver.describe(
266
+ req('openwop.it.ai-envelope-shape.accepted-outcome-carries-normalizedmeta-contenttrust-per-rfc-0021-a-point-6',
265
267
  'RFC 0021 §A point 6',
266
268
  'host MUST propagate runTrustBoundary onto normalizedMeta.contentTrust when envelope meta.contentTrust is absent',
267
269
  ),
@@ -280,12 +282,12 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
280
282
  },
281
283
  runTrustBoundary: 'untrusted', // explicitly conflicts; envelope wins
282
284
  });
283
- if (res.status === 404) return;
285
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (seam, prior step, or fixture unavailable)');
284
286
  const body = res.json as { status?: string; normalizedMeta?: { contentTrust?: string } };
285
287
  expect(body.status).toBe('accepted');
286
288
  expect(
287
289
  body.normalizedMeta?.contentTrust,
288
- driver.describe(
290
+ req('openwop.it.ai-envelope-shape.envelope-supplied-meta-contenttrust-takes-precedence-over-runtrustboundary',
289
291
  'RFC 0021 §A point 6',
290
292
  'envelope meta.contentTrust MUST take precedence over runTrustBoundary',
291
293
  ),
@@ -303,9 +305,9 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
303
305
  meta: { source: 'ai-generation', ts: 'tomorrow' },
304
306
  },
305
307
  });
306
- if (res.status === 404) return;
308
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (seam, prior step, or fixture unavailable)');
307
309
  const body = res.json as { status?: string; reason?: string };
308
- expect(body.status, 'malformed timestamp MUST be rejected').toBe('invalid');
310
+ expect(body.status, req('openwop.it.ai-envelope-shape.non-iso-8601-meta-ts-status-invalid-format-defense-in-depth', 'RFC 0021 §D', 'malformed timestamp MUST be rejected')).toBe('invalid');
309
311
  expect(body.reason).toContain('ISO 8601');
310
312
  });
311
313
 
@@ -321,12 +323,12 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
321
323
  },
322
324
  nodeAllowedKinds: ['vendor.acme.prd.create'], // doesn't include clarification.request
323
325
  });
324
- if (res.status === 404) return;
326
+ if (res.status === 404) return softSkip('blocked', 'precondition not met — `res.status === 404` returned early (seam, prior step, or fixture unavailable)');
325
327
  expect(res.status).toBe(200);
326
328
  const body = res.json as { status?: string };
327
329
  expect(
328
330
  body.status,
329
- driver.describe(
331
+ req('openwop.it.ai-envelope-shape.universal-kind-allowed-regardless-of-nodeallowedkinds-always-allowed-per-univers',
330
332
  'RFC 0021 §"Universal kinds (normative)"',
331
333
  'universal kinds MUST be allowed even when node allowlist excludes them',
332
334
  ),
@@ -337,12 +339,12 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: behavioral acceptEnvelope round-t
337
339
  describe.skipIf(HTTP_SKIP)('ai-envelope-shape: universal-kind advertisement (RFC 0021 §C)', () => {
338
340
  it('host advertising any universal kind has a matching schema on disk', async () => {
339
341
  const d = await readDiscovery();
340
- if (d === null || !aiProvidersSupported(d)) return; // capability-gated
342
+ if (d === null || !aiProvidersSupported(d)) return softSkip('blocked', 'precondition not met — `d === null || !aiProvidersSupported(d)` returned early (capability-gated) (seam, prior step, or fixture unavailable)'); // capability-gated
341
343
  const env = supportedEnvelopes(d);
342
344
  const advertisedUniversals = env.filter((k): k is (typeof UNIVERSAL_KINDS)[number] =>
343
345
  (UNIVERSAL_KINDS as readonly string[]).includes(k),
344
346
  );
345
- if (advertisedUniversals.length === 0) return; // host doesn't claim any universal
347
+ if (advertisedUniversals.length === 0) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `advertisedUniversals.length === 0` returned early (host doesn\'t claim any universal)'); // host doesn't claim any universal
346
348
  // Each advertised universal MUST have its schema compileable (already
347
349
  // covered by the per-kind compile test above; this assertion just makes
348
350
  // the linkage between advertisement + schema explicit).
@@ -351,7 +353,7 @@ describe.skipIf(HTTP_SKIP)('ai-envelope-shape: universal-kind advertisement (RFC
351
353
  const schema = JSON.parse(readFileSync(join(SCHEMAS_DIR, `envelopes/${k}.schema.json`), 'utf8')) as Record<string, unknown>;
352
354
  expect(
353
355
  ajv.compile(schema),
354
- `RFC 0021 §B: advertised universal ${k} MUST resolve to a compileable schema`,
356
+ req('openwop.it.ai-envelope-shape.host-advertising-any-universal-kind-has-a-matching-schema-on-disk', 'RFC 0021 §D', `RFC 0021 §B: advertised universal ${k} MUST resolve to a compileable schema`),
355
357
  ).toBeTypeOf('function');
356
358
  }
357
359
  });
@@ -42,14 +42,14 @@ describe('aiEnvelope.capBreached: advertisement shape (already required v1)', ()
42
42
  const limits = await readLimits();
43
43
  expect(
44
44
  limits,
45
- driver.describe(
45
+ req('openwop.it.aiEnvelope.capBreached.limits-envelopesperturn-is-a-non-negative-integer',
46
46
  'capabilities.schema.json §limits',
47
47
  'limits MUST be present on /.well-known/openwop (required v1)',
48
48
  ),
49
49
  ).not.toBeNull();
50
50
  expect(
51
51
  Number.isInteger(limits!.envelopesPerTurn) && limits!.envelopesPerTurn >= 0,
52
- driver.describe(
52
+ req('openwop.it.aiEnvelope.capBreached.limits-envelopesperturn-is-a-non-negative-integer',
53
53
  'capabilities.schema.json §limits.envelopesPerTurn',
54
54
  'envelopesPerTurn MUST be a non-negative integer (required v1)',
55
55
  ),
@@ -58,10 +58,10 @@ describe('aiEnvelope.capBreached: advertisement shape (already required v1)', ()
58
58
 
59
59
  it('limits.schemaRounds is a non-negative integer', async () => {
60
60
  const limits = await readLimits();
61
- if (limits === null) return;
61
+ if (limits === null) return softSkip('blocked', 'precondition not met — `limits === null` returned early (seam, prior step, or fixture unavailable)');
62
62
  expect(
63
63
  Number.isInteger(limits.schemaRounds) && limits.schemaRounds >= 0,
64
- driver.describe(
64
+ req('openwop.it.aiEnvelope.capBreached.limits-schemarounds-is-a-non-negative-integer',
65
65
  'capabilities.schema.json §limits.schemaRounds',
66
66
  'schemaRounds MUST be a non-negative integer (required v1)',
67
67
  ),
@@ -70,10 +70,10 @@ describe('aiEnvelope.capBreached: advertisement shape (already required v1)', ()
70
70
 
71
71
  it('limits.clarificationRounds is a non-negative integer', async () => {
72
72
  const limits = await readLimits();
73
- if (limits === null) return;
73
+ if (limits === null) return softSkip('blocked', 'precondition not met — `limits === null` returned early (seam, prior step, or fixture unavailable)');
74
74
  expect(
75
75
  Number.isInteger(limits.clarificationRounds) && limits.clarificationRounds >= 0,
76
- driver.describe(
76
+ req('openwop.it.aiEnvelope.capBreached.limits-clarificationrounds-is-a-non-negative-integer',
77
77
  'capabilities.schema.json §limits.clarificationRounds',
78
78
  'clarificationRounds MUST be a non-negative integer (required v1)',
79
79
  ),
@@ -101,10 +101,10 @@ describe('aiEnvelope.capBreached: behavioral cap enforcement (FINAL v1.1)', () =
101
101
  },
102
102
  { counters: { envelopesPerTurn: { current: 32, cap: 32 } } },
103
103
  );
104
- if (r.status === 404) return;
104
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
105
105
  expect(
106
106
  r.body.status,
107
- driver.describe('ai-envelope.md §"Engine-enforced limits"', 'over-cap envelope MUST be breached'),
107
+ req('openwop.it.aiEnvelope.capBreached.envelopesperturn-at-cap-status-breached-capkind-envelopes', 'ai-envelope.md §"Engine-enforced limits"', 'over-cap envelope MUST be breached'),
108
108
  ).toBe('breached');
109
109
  expect(r.body.capKind).toBe('envelopes');
110
110
  });
@@ -121,8 +121,8 @@ describe('aiEnvelope.capBreached: behavioral cap enforcement (FINAL v1.1)', () =
121
121
  },
122
122
  { counters: { clarificationRounds: { current: 5, cap: 5 } } },
123
123
  );
124
- if (r.status === 404) return;
125
- expect(r.body.status).toBe('breached');
124
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
125
+ expect(r.body.status, req('openwop.it.aiEnvelope.capBreached.clarificationrounds-at-cap-status-breached-capkind-clarification', 'spec/v1/ai-envelope.md', 'clarificationRounds at cap → status: breached { capKind: "clarification" }')).toBe('breached');
126
126
  expect(r.body.capKind).toBe('clarification');
127
127
  });
128
128
 
@@ -138,8 +138,8 @@ describe('aiEnvelope.capBreached: behavioral cap enforcement (FINAL v1.1)', () =
138
138
  },
139
139
  { counters: { schemaRounds: { current: 3, cap: 3 } } },
140
140
  );
141
- if (r.status === 404) return;
142
- expect(r.body.status).toBe('breached');
141
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
142
+ expect(r.body.status, req('openwop.it.aiEnvelope.capBreached.schemarounds-at-cap-status-breached-capkind-schema', 'spec/v1/ai-envelope.md', 'schemaRounds at cap → status: breached { capKind: "schema" }')).toBe('breached');
143
143
  expect(r.body.capKind).toBe('schema');
144
144
  });
145
145
 
@@ -155,8 +155,8 @@ describe('aiEnvelope.capBreached: behavioral cap enforcement (FINAL v1.1)', () =
155
155
  },
156
156
  { counters: { envelopesPerTurn: { current: 32, cap: 32 } } },
157
157
  );
158
- if (r.status === 404) return;
159
- expect(r.body.reason).toContain('envelopesPerTurn');
158
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
159
+ expect(r.body.reason, req('openwop.it.aiEnvelope.capBreached.breached-reason-cites-the-limit-and-cap-value', 'spec/v1/ai-envelope.md', 'breached reason cites the limit and cap value')).toContain('envelopesPerTurn');
160
160
  expect(r.body.reason).toContain('32');
161
161
  });
162
162
  });
@@ -167,10 +167,12 @@ describe('aiEnvelope.capBreached: behavioral cap enforcement (FINAL v1.1)', () =
167
167
  // soft-skip on HTTP 404 when the seam isn't exposed.
168
168
  import { queryTestEvents, isEventLogSeamAvailable, resetTestSeam } from '../lib/event-log-query.js';
169
169
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
170
+ import { req } from '../lib/requirement-ids.js';
171
+ import { softSkip } from '../lib/soft-skip.js';
170
172
 
171
173
  describe('aiEnvelope.capBreached: engine projection via event-log seam (capabilities.md §"cap.breached")', () => {
172
174
  it('breached outcome projects to cap.breached { kind: "envelopes" } event with causationId chain', async () => {
173
- if (!(await isEventLogSeamAvailable())) return;
175
+ if (!(await isEventLogSeamAvailable())) return softSkip('blocked', 'precondition not met — `!(await isEventLogSeamAvailable())` returned early (seam, prior step, or fixture unavailable)');
174
176
  const runId = `r-cap-env-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
175
177
  const correlationId = `${runId}:node-1:turn-0:cap-env`;
176
178
  const r = await accept(
@@ -187,14 +189,14 @@ describe('aiEnvelope.capBreached: engine projection via event-log seam (capabili
187
189
  projectTo: { runId, nodeId: 'node-1' },
188
190
  },
189
191
  );
190
- if (r.status === 404) return;
192
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
191
193
  expect(r.body.status).toBe('breached');
192
194
 
193
195
  const events = await queryTestEvents(runId, { type: 'cap.breached' });
194
- if (!events.ok) return;
196
+ if (!events.ok) return softSkip('blocked', 'precondition not met — `!events.ok` returned early (seam, prior step, or fixture unavailable)');
195
197
  expect(
196
198
  events.events.length,
197
- driver.describe('capabilities.md §"Engine-enforced limits and the cap.breached event"', 'breached outcome MUST project to exactly one cap.breached event'),
199
+ req('openwop.it.aiEnvelope.capBreached.breached-outcome-projects-to-cap-breached-kind-envelopes-event-with-causationid', 'capabilities.md §"Engine-enforced limits and the cap.breached event"', 'breached outcome MUST project to exactly one cap.breached event'),
198
200
  ).toBe(1);
199
201
  const evt = events.events[0]!;
200
202
  expect(evt.payload.kind).toBe('envelopes');
@@ -203,7 +205,7 @@ describe('aiEnvelope.capBreached: engine projection via event-log seam (capabili
203
205
  });
204
206
 
205
207
  it('cap.breached payload includes limit, observed, and nodeId per capabilities.md', async () => {
206
- if (!(await isEventLogSeamAvailable())) return;
208
+ if (!(await isEventLogSeamAvailable())) return softSkip('blocked', 'precondition not met — `!(await isEventLogSeamAvailable())` returned early (seam, prior step, or fixture unavailable)');
207
209
  const runId = `r-cap-payload-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
208
210
  await accept(
209
211
  {
@@ -220,19 +222,19 @@ describe('aiEnvelope.capBreached: engine projection via event-log seam (capabili
220
222
  },
221
223
  );
222
224
  const events = await queryTestEvents(runId, { type: 'cap.breached' });
223
- if (!events.ok || events.events.length === 0) return;
225
+ if (!events.ok || events.events.length === 0) return softSkip('blocked', 'precondition not met — `!events.ok || events.events.length === 0` returned early (seam, prior step, or fixture unavailable)');
224
226
  const evt = events.events[0]!;
225
227
  expect(evt.payload.kind).toBe('clarification');
226
228
  expect(
227
229
  typeof evt.payload.limit,
228
- driver.describe('capabilities.md §"cap.breached"', 'payload.limit MUST be present as a number'),
230
+ req('openwop.it.aiEnvelope.capBreached.cap-breached-payload-includes-limit-observed-and-nodeid-per-capabilities-md', 'capabilities.md §"cap.breached"', 'payload.limit MUST be present as a number'),
229
231
  ).toBe('number');
230
232
  expect(evt.payload.nodeId).toBe('node-2');
231
233
  await resetTestSeam();
232
234
  });
233
235
 
234
236
  it('cap.breached MUST be paired with a terminal node.failed transition', async () => {
235
- if (!(await isEventLogSeamAvailable())) return;
237
+ if (!(await isEventLogSeamAvailable())) return softSkip('blocked', 'precondition not met — `!(await isEventLogSeamAvailable())` returned early (seam, prior step, or fixture unavailable)');
236
238
  const runId = `r-cap-fail-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
237
239
  await accept(
238
240
  {
@@ -250,11 +252,11 @@ describe('aiEnvelope.capBreached: engine projection via event-log seam (capabili
250
252
  );
251
253
  const breached = await queryTestEvents(runId, { type: 'cap.breached' });
252
254
  const failed = await queryTestEvents(runId, { type: 'node.failed' });
253
- if (!breached.ok || !failed.ok) return;
255
+ if (!breached.ok || !failed.ok) return softSkip('blocked', 'precondition not met — `!breached.ok || !failed.ok` returned early (seam, prior step, or fixture unavailable)');
254
256
  expect(breached.events.length).toBe(1);
255
257
  expect(
256
258
  failed.events.length,
257
- driver.describe('capabilities.md §"cap.breached"', 'cap.breached MUST be paired with a terminal node.failed event'),
259
+ req('openwop.it.aiEnvelope.capBreached.cap-breached-must-be-paired-with-a-terminal-node-failed-transition', 'capabilities.md §"cap.breached"', 'cap.breached MUST be paired with a terminal node.failed event'),
258
260
  ).toBe(1);
259
261
  expect((failed.events[0]!.payload.error as { code?: string }).code).toBe('cap_breached');
260
262
  await resetTestSeam();