@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
@@ -64,10 +64,10 @@ async function emit(input: Record<string, unknown>): Promise<{ status: number; b
64
64
  describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: seam emission (RFC 0032 §B.3 MUST)', () => {
65
65
  it('accepts a well-formed `envelope.refusal` payload + writes it to the test event log', async () => {
66
66
  const d = await readDiscovery();
67
- if (d === null) return;
67
+ if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
68
68
  const reliability = capabilityFamily<{ reasoning?: Record<string, unknown>; tierOneSubsetCompliance?: unknown; reliability?: { completion?: Record<string, unknown> } & Record<string, unknown> }>(d, 'envelopes')?.reliability;
69
- if (!reliability || reliability.supported !== true) return;
70
- if (!Array.isArray(reliability.events) || !(reliability.events as unknown[]).includes('envelope.refusal')) return;
69
+ if (!reliability || reliability.supported !== true) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!reliability || reliability.supported !== true` returned early');
70
+ if (!Array.isArray(reliability.events) || !(reliability.events as unknown[]).includes('envelope.refusal')) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!Array.isArray(reliability.events) || !(reliability.events as unknown[]).includes(\'envelope.refusal\')` returned early');
71
71
 
72
72
  const r = await emit({
73
73
  runId: 'conformance-refusal-1',
@@ -81,10 +81,10 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: seam emission (RFC 0032 §B.
81
81
  },
82
82
  nodeId: 'writer',
83
83
  });
84
- if (r.status === 404) return;
84
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
85
85
  expect(
86
86
  r.status,
87
- driver.describe(
87
+ req('openwop.it.envelope-refusal-shape.accepts-a-well-formed-envelope-refusal-payload-writes-it-to-the-test-event-log',
88
88
  'schemas/run-event-payloads.schema.json §envelopeRefusal',
89
89
  'a payload with the required {nodeId, provider, model} fields MUST be accepted by the seam',
90
90
  ),
@@ -108,10 +108,10 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: seam emission (RFC 0032 §B.
108
108
  safetyCategory: 'harmful-content',
109
109
  },
110
110
  });
111
- if (r.status === 404) return;
111
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
112
112
  expect(
113
113
  r.status,
114
- driver.describe(
114
+ req('openwop.it.envelope-refusal-shape.rejects-payloads-with-refusaltext-containing-a-secret-canary-substring-byok-leak',
115
115
  'SECURITY/invariants.yaml §envelope-refusal-no-prompt-leak',
116
116
  'envelope.refusal.refusalText MUST be passed through the host BYOK redaction harness; seam refuses payloads carrying secret-canary-* substrings (defense-in-depth CI gate per RFC 0032 §B.3 + §G)',
117
117
  ),
@@ -130,8 +130,8 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: seam emission (RFC 0032 §B.
130
130
  credentialRef: 'secret-byok-abc123', // forbidden
131
131
  },
132
132
  });
133
- if (r.status === 404) return;
134
- expect(r.status).toBe(400);
133
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
134
+ expect(r.status, req('openwop.it.envelope-refusal-shape.rejects-payloads-with-a-top-level-credentialref-field', 'RFC 0032 §B.3', 'rejects payloads with a top-level `credentialRef` field')).toBe(400);
135
135
  expect(readErrorCode(r.body)).toBe('envelope_reliability_credential_leak');
136
136
  });
137
137
 
@@ -145,8 +145,8 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: seam emission (RFC 0032 §B.
145
145
  model: 'claude-3-5-sonnet',
146
146
  },
147
147
  });
148
- if (r.status === 404) return;
149
- expect(r.status).toBe(400);
148
+ if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
149
+ expect(r.status, req('openwop.it.envelope-refusal-shape.rejects-payloads-missing-required-provider-field', 'RFC 0032 §B.3', 'rejects payloads missing required `provider` field')).toBe(400);
150
150
  expect(readErrorCode(r.body)).toBe('invalid_argument');
151
151
  });
152
152
  });
@@ -154,25 +154,25 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: seam emission (RFC 0032 §B.
154
154
  describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: advertisement contract (RFC 0032 §C)', () => {
155
155
  it('capabilities.envelopes.reliability (when supported: true with non-empty events[]) MUST list both MUST-tier events', async () => {
156
156
  const d = await readDiscovery();
157
- if (d === null) return;
157
+ if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
158
158
  const reliability = capabilityFamily<{ reasoning?: Record<string, unknown>; tierOneSubsetCompliance?: unknown; reliability?: { completion?: Record<string, unknown> } & Record<string, unknown> }>(d, 'envelopes')?.reliability;
159
- if (!reliability || reliability.supported !== true) return;
159
+ if (!reliability || reliability.supported !== true) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!reliability || reliability.supported !== true` returned early');
160
160
  // Hosts running the legacy undifferentiated retry loop advertise
161
161
  // `events: []` (per the OPENWOP_ENVELOPE_RELIABILITY_END_TO_END=false
162
162
  // operator override). The two MUST-tier events still surface through
163
163
  // the test seam in that case; the advertisement-shape MUST applies
164
164
  // only when events[] is non-empty.
165
- if (!Array.isArray(reliability.events) || (reliability.events as unknown[]).length === 0) return;
165
+ if (!Array.isArray(reliability.events) || (reliability.events as unknown[]).length === 0) return softSkip('blocked', 'precondition not met — `!Array.isArray(reliability.events) || (reliability.events as unknown[]).length === 0` returned early (Hosts running the legacy undifferentiated retry loop advertise `events: []` (per the OPENWO…');
166
166
  expect(
167
167
  (reliability.events as unknown[]).includes('envelope.refusal'),
168
- driver.describe(
168
+ req('openwop.it.envelope-refusal-shape.capabilities-envelopes-reliability-when-supported-true-with-non-empty-events-mus',
169
169
  'RFCS/0032-envelope-reliability-events.md §C',
170
170
  'hosts that advertise reliability.supported: true with non-empty events[] MUST include envelope.refusal (one of the two MUST-tier events per RFC 0032 §C normative text)',
171
171
  ),
172
172
  ).toBe(true);
173
173
  expect(
174
174
  (reliability.events as unknown[]).includes('envelope.retry.exhausted'),
175
- driver.describe(
175
+ req('openwop.it.envelope-refusal-shape.capabilities-envelopes-reliability-when-supported-true-with-non-empty-events-mus',
176
176
  'RFCS/0032-envelope-reliability-events.md §C',
177
177
  'hosts that advertise reliability.supported: true with non-empty events[] MUST also include envelope.retry.exhausted (the other MUST-tier event; both MUSTs land together)',
178
178
  ),
@@ -192,6 +192,8 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: advertisement contract (RFC
192
192
  import { pollUntilTerminal } from '../lib/polling.js';
193
193
  import { isFixtureAdvertised } from '../lib/fixtures.js';
194
194
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
195
+ import { req } from '../lib/requirement-ids.js';
196
+ import { softSkip } from '../lib/soft-skip.js';
195
197
 
196
198
  const E2E_FIXTURE = 'conformance-envelope-refusal';
197
199
  const E2E_NODE_ID = 'structured-call';
@@ -224,17 +226,17 @@ async function runE2eAndRead(): Promise<{ events: E2eEvent[]; terminal: unknown
224
226
 
225
227
  describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: end-to-end refusal through dispatchStructured', () => {
226
228
  it('when mock provider returns stopReason: "safety" with refusalText, host emits exactly one envelope.refusal event AND does NOT retry', async () => {
227
- if (!isFixtureAdvertised(E2E_FIXTURE)) return;
229
+ if (!isFixtureAdvertised(E2E_FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(E2E_FIXTURE)` returned early');
228
230
  const seed = await programMockRefusal('I cannot help with that — safety filter triggered.');
229
- if (seed.status === 404) return;
231
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
230
232
  expect(seed.status).toBe(200);
231
233
 
232
234
  const result = await runE2eAndRead();
233
- if (result === null) return;
235
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
234
236
  const refusals = result.events.filter((e) => e.type === 'envelope.refusal');
235
237
  expect(
236
238
  refusals.length,
237
- driver.describe(
239
+ req('openwop.it.envelope-refusal-shape.when-mock-provider-returns-stopreason-safety-with-refusaltext-host-emits-exactly',
238
240
  'RFCS/0032-envelope-reliability-events.md §B.3',
239
241
  'exactly one envelope.refusal event MUST fire on provider safety-stop',
240
242
  ),
@@ -243,7 +245,7 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: end-to-end refusal through d
243
245
  const retries = result.events.filter((e) => e.type === 'envelope.retry.attempted');
244
246
  expect(
245
247
  retries.length,
246
- driver.describe(
248
+ req('openwop.it.envelope-refusal-shape.when-mock-provider-returns-stopreason-safety-with-refusaltext-host-emits-exactly',
247
249
  'RFCS/0033-envelope-completion-contract.md §D',
248
250
  'host MUST NOT retry after envelope.refusal (refusal is terminal — retrying with prompt mutation creates a circumvention concern)',
249
251
  ),
@@ -251,16 +253,16 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: end-to-end refusal through d
251
253
  });
252
254
 
253
255
  it('node fails with RunSnapshot.error.code = "envelope_refusal" per RFC 0033 §F', async () => {
254
- if (!isFixtureAdvertised(E2E_FIXTURE)) return;
256
+ if (!isFixtureAdvertised(E2E_FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(E2E_FIXTURE)` returned early');
255
257
  const seed = await programMockRefusal('Refusal text for terminal-error-code assertion.');
256
- if (seed.status === 404) return;
258
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
257
259
 
258
260
  const result = await runE2eAndRead();
259
- if (result === null) return;
261
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
260
262
  const code = (result.terminal as { error?: { code?: string } }).error?.code;
261
263
  expect(
262
264
  code,
263
- driver.describe(
265
+ req('openwop.it.envelope-refusal-shape.node-fails-with-runsnapshot-error-code-envelope-refusal-per-rfc-0033-f',
264
266
  'RFCS/0033-envelope-completion-contract.md §F',
265
267
  'refusal-driven failure MUST surface as RunSnapshot.error.code = envelope_refusal (renamed 2026-05-21 from envelope_refused_by_provider per the MyndHyve adoption-feedback amendment)',
266
268
  ),
@@ -268,21 +270,21 @@ describe.skipIf(HTTP_SKIP)('envelope-refusal-shape: end-to-end refusal through d
268
270
  });
269
271
 
270
272
  it('RunSnapshot.error.message MUST NOT echo the providers refusal text (SECURITY invariant envelope-refusal-no-prompt-leak)', async () => {
271
- if (!isFixtureAdvertised(E2E_FIXTURE)) return;
273
+ if (!isFixtureAdvertised(E2E_FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(E2E_FIXTURE)` returned early');
272
274
  // A distinctive refusal text so the message-no-echo assertion has
273
275
  // a unique substring to scan for. Production refusal texts may
274
276
  // contain prompt content; the host MUST keep it off the error
275
277
  // message surface (event log only, scrubbed via SR-1).
276
278
  const REFUSAL_TEXT = 'REFUSAL-CANARY-A8F3-do-not-echo-this-substring-into-RunSnapshot.error.message';
277
279
  const seed = await programMockRefusal(REFUSAL_TEXT);
278
- if (seed.status === 404) return;
280
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
279
281
 
280
282
  const result = await runE2eAndRead();
281
- if (result === null) return;
283
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
282
284
  const message = (result.terminal as { error?: { message?: string } }).error?.message ?? '';
283
285
  expect(
284
286
  message.includes(REFUSAL_TEXT),
285
- driver.describe(
287
+ req('openwop.it.envelope-refusal-shape.runsnapshot-error-message-must-not-echo-the-providers-refusal-text-security-inva',
286
288
  'SECURITY/invariants.yaml §envelope-refusal-no-prompt-leak',
287
289
  'RunSnapshot.error.message MUST NOT echo refusalText — the safety-filter text may contain prompt content; spec-compliant emission carries it only on the envelope.refusal event payload (subject to SR-1 redaction at the eventLog.append boundary)',
288
290
  ),
@@ -24,6 +24,7 @@ import addFormats from 'ajv-formats';
24
24
  import { readFileSync } from 'node:fs';
25
25
  import { join } from 'node:path';
26
26
  import { SCHEMAS_DIR } from '../lib/paths.js';
27
+ import { req } from '../lib/requirement-ids.js';
27
28
 
28
29
  function compileEnvelope(): ReturnType<Ajv2020['compile']> {
29
30
  const ajv = new Ajv2020({ strict: false, allErrors: true });
@@ -57,7 +58,7 @@ describe('envelope-rendering-hint: meta.rendering shape (RFC 0055 §B)', () => {
57
58
  const ok = validate(env);
58
59
  expect(
59
60
  ok,
60
- 'ai-envelope.md §"Rendering hints": ' + `meta.rendering MUST validate; errors: ${JSON.stringify(validate.errors)}`,
61
+ req('openwop.it.envelope-rendering-hint.accepts-an-envelope-carrying-a-well-formed-meta-rendering-hint', 'RFC 0055 §B', 'ai-envelope.md §"Rendering hints": ' + `meta.rendering MUST validate; errors: ${JSON.stringify(validate.errors)}`),
61
62
  ).toBe(true);
62
63
  });
63
64
 
@@ -65,7 +66,7 @@ describe('envelope-rendering-hint: meta.rendering shape (RFC 0055 §B)', () => {
65
66
  const ok = validate(baseEnvelope);
66
67
  expect(
67
68
  ok,
68
- 'ai-envelope.md §"Rendering hints": ' + 'meta.rendering MUST be optional — envelopes omitting it still validate',
69
+ req('openwop.it.envelope-rendering-hint.accepts-an-envelope-with-no-meta-rendering-proves-the-property-is-optional', 'RFC 0055 §B', 'ai-envelope.md §"Rendering hints": ' + 'meta.rendering MUST be optional — envelopes omitting it still validate'),
69
70
  ).toBe(true);
70
71
  });
71
72
 
@@ -77,7 +78,7 @@ describe('envelope-rendering-hint: meta.rendering shape (RFC 0055 §B)', () => {
77
78
  const ok = validate(env);
78
79
  expect(
79
80
  ok,
80
- 'ai-envelope.md §"Rendering hints": ' + 'display is a closed enum — unknown families MUST be rejected',
81
+ req('openwop.it.envelope-rendering-hint.rejects-an-unknown-display-value-closed-enum', 'RFC 0055 §B', 'ai-envelope.md §"Rendering hints": ' + 'display is a closed enum — unknown families MUST be rejected'),
81
82
  ).toBe(false);
82
83
  });
83
84
 
@@ -89,7 +90,7 @@ describe('envelope-rendering-hint: meta.rendering shape (RFC 0055 §B)', () => {
89
90
  const ok = validate(env);
90
91
  expect(
91
92
  ok,
92
- 'ai-envelope.md §"Rendering hints": ' + 'rendering is additionalProperties:false',
93
+ req('openwop.it.envelope-rendering-hint.rejects-an-unknown-property-under-rendering-additionalproperties-false', 'RFC 0055 §B', 'ai-envelope.md §"Rendering hints": ' + 'rendering is additionalProperties:false'),
93
94
  ).toBe(false);
94
95
  });
95
96
  });
@@ -58,12 +58,12 @@ async function readDiscovery(): Promise<DiscoveryDoc | null> {
58
58
  describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: advertisement shape (RFC 0032 §C)', () => {
59
59
  it('capabilities.envelopes.reliability (when present) conforms to RFC 0032 §C', async () => {
60
60
  const d = await readDiscovery();
61
- if (d === null) return;
61
+ if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
62
62
  const reliability = capabilityFamily<{ reasoning?: Record<string, unknown>; tierOneSubsetCompliance?: unknown; reliability?: { completion?: Record<string, unknown> } & Record<string, unknown> }>(d, 'envelopes')?.reliability;
63
- if (reliability === undefined) return;
64
- expect(typeof reliability.supported, 'reliability.supported MUST be boolean').toBe('boolean');
63
+ if (reliability === undefined) return softSkip('blocked', 'precondition not met — `reliability === undefined` returned early (seam, prior step, or fixture unavailable)');
64
+ expect(typeof reliability.supported, req('openwop.it.envelope-retry-attempted.capabilities-envelopes-reliability-when-present-conforms-to-rfc-0032-c', 'RFC 0032 §C', 'reliability.supported MUST be boolean')).toBe('boolean');
65
65
  if (reliability.events !== undefined) {
66
- expect(Array.isArray(reliability.events), 'reliability.events MUST be an array').toBe(true);
66
+ expect(Array.isArray(reliability.events), req('openwop.it.envelope-retry-attempted.capabilities-envelopes-reliability-when-present-conforms-to-rfc-0032-c', 'RFC 0032 §C', 'reliability.events MUST be an array')).toBe(true);
67
67
  const RFC_0032_EVENTS = [
68
68
  'envelope.retry.attempted',
69
69
  'envelope.retry.exhausted',
@@ -73,7 +73,7 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: advertisement shape (RFC 0
73
73
  'envelope.recovery.applied',
74
74
  ];
75
75
  for (const e of reliability.events as unknown[]) {
76
- expect(RFC_0032_EVENTS, `event "${String(e)}" MUST be one of the six RFC 0032 names`).toContain(String(e));
76
+ expect(RFC_0032_EVENTS, req('openwop.it.envelope-retry-attempted.capabilities-envelopes-reliability-when-present-conforms-to-rfc-0032-c', 'RFC 0032 §C', `event "${String(e)}" MUST be one of the six RFC 0032 names`)).toContain(String(e));
77
77
  }
78
78
  // When supported: true, MUST include the two MUST-tier events (per
79
79
  // RFC 0032 §C). Hosts that have wired end-to-end emission from
@@ -87,17 +87,17 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: advertisement shape (RFC 0
87
87
  const evts = reliability.events as string[];
88
88
  expect(
89
89
  evts.includes('envelope.retry.exhausted'),
90
- 'RFC 0032 §C: hosts that advertise `supported: true` with non-empty `events[]` MUST include `envelope.retry.exhausted`',
90
+ req('openwop.it.envelope-retry-attempted.capabilities-envelopes-reliability-when-present-conforms-to-rfc-0032-c', 'RFC 0032 §C', 'RFC 0032 §C: hosts that advertise `supported: true` with non-empty `events[]` MUST include `envelope.retry.exhausted`'),
91
91
  ).toBe(true);
92
92
  expect(
93
93
  evts.includes('envelope.refusal'),
94
- 'RFC 0032 §C: hosts that advertise `supported: true` with non-empty `events[]` MUST include `envelope.refusal`',
94
+ req('openwop.it.envelope-retry-attempted.capabilities-envelopes-reliability-when-present-conforms-to-rfc-0032-c', 'RFC 0032 §C', 'RFC 0032 §C: hosts that advertise `supported: true` with non-empty `events[]` MUST include `envelope.refusal`'),
95
95
  ).toBe(true);
96
96
  }
97
97
  }
98
98
  if (reliability.maxRetryAttempts !== undefined) {
99
99
  const n = reliability.maxRetryAttempts as number;
100
- expect(typeof n === 'number' && n >= 1 && n <= 16, 'maxRetryAttempts MUST be integer in [1, 16]').toBe(true);
100
+ expect(typeof n === 'number' && n >= 1 && n <= 16, req('openwop.it.envelope-retry-attempted.capabilities-envelopes-reliability-when-present-conforms-to-rfc-0032-c', 'RFC 0032 §C', 'maxRetryAttempts MUST be integer in [1, 16]')).toBe(true);
101
101
  }
102
102
  });
103
103
  });
@@ -115,6 +115,8 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: advertisement shape (RFC 0
115
115
  import { pollUntilTerminal } from '../lib/polling.js';
116
116
  import { isFixtureAdvertised } from '../lib/fixtures.js';
117
117
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
118
+ import { req } from '../lib/requirement-ids.js';
119
+ import { softSkip } from '../lib/soft-skip.js';
118
120
 
119
121
  const FIXTURE = 'conformance-envelope-retry-attempted';
120
122
  const NODE_ID = 'structured-call';
@@ -154,20 +156,20 @@ async function startRunAndRead(): Promise<RunEvent[] | null> {
154
156
 
155
157
  describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: runtime behavior (RFC 0032 §B.1)', () => {
156
158
  it('when mock LLM emits invalid envelope on attempt 1 then valid on attempt 2, exactly one `envelope.retry.attempted` event fires before the second attempt', async () => {
157
- if (!isFixtureAdvertised(FIXTURE)) return;
159
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
158
160
  const seed = await programMock([
159
161
  { content: 'not valid json — provoke parse-error retry' },
160
162
  { content: '{"valid":true}' },
161
163
  ]);
162
- if (seed.status === 404) return; // host doesn't expose the seam
164
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (host doesn\'t expose the seam) (seam, prior step, or fixture unavailable)'); // host doesn't expose the seam
163
165
  expect(seed.status).toBe(200);
164
166
 
165
167
  const events = await startRunAndRead();
166
- if (events === null) return;
168
+ if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
167
169
  const retries = events.filter((e) => e.type === 'envelope.retry.attempted');
168
170
  expect(
169
171
  retries.length,
170
- driver.describe(
172
+ req('openwop.it.envelope-retry-attempted.when-mock-llm-emits-invalid-envelope-on-attempt-1-then-valid-on-attempt-2-exactl',
171
173
  'RFCS/0032-envelope-reliability-events.md §B.1',
172
174
  'exactly one envelope.retry.attempted event MUST fire between attempts 1 and 2',
173
175
  ),
@@ -175,17 +177,17 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: runtime behavior (RFC 0032
175
177
  });
176
178
 
177
179
  it('event payload carries `attempt: 2` (1-indexed; first attempt does not emit)', async () => {
178
- if (!isFixtureAdvertised(FIXTURE)) return;
180
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
179
181
  const seed = await programMock([{ content: 'invalid' }, { content: '{"valid":true}' }]);
180
- if (seed.status === 404) return;
182
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
181
183
 
182
184
  const events = await startRunAndRead();
183
- if (events === null) return;
185
+ if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
184
186
  const retry = events.find((e) => e.type === 'envelope.retry.attempted');
185
- expect(retry, 'envelope.retry.attempted MUST appear in the event log').toBeDefined();
187
+ expect(retry, req('openwop.it.envelope-retry-attempted.event-payload-carries-attempt-2-1-indexed-first-attempt-does-not-emit', 'RFCS/0032-envelope-reliability-events.md §B.1', 'envelope.retry.attempted MUST appear in the event log')).toBeDefined();
186
188
  expect(
187
189
  retry!.payload?.attempt,
188
- driver.describe(
190
+ req('openwop.it.envelope-retry-attempted.event-payload-carries-attempt-2-1-indexed-first-attempt-does-not-emit',
189
191
  'RFCS/0032-envelope-reliability-events.md §B.1',
190
192
  'attempt field MUST be 2 (1-indexed; first attempt does not emit)',
191
193
  ),
@@ -193,19 +195,19 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: runtime behavior (RFC 0032
193
195
  });
194
196
 
195
197
  it('`reason` is one of the spec-reserved closed-enum values OR matches the `x-host-<host>-<key>` extension pattern', async () => {
196
- if (!isFixtureAdvertised(FIXTURE)) return;
198
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
197
199
  const seed = await programMock([{ content: 'invalid' }, { content: '{"valid":true}' }]);
198
- if (seed.status === 404) return;
200
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
199
201
 
200
202
  const events = await startRunAndRead();
201
- if (events === null) return;
203
+ if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
202
204
  const retry = events.find((e) => e.type === 'envelope.retry.attempted');
203
205
  expect(retry).toBeDefined();
204
206
  const reason = retry!.payload?.reason;
205
207
  expect(typeof reason).toBe('string');
206
208
  expect(
207
209
  RFC_0032_REASONS.has(reason as string) || HOST_REASON_EXT_RE.test(reason as string),
208
- driver.describe(
210
+ req('openwop.it.envelope-retry-attempted.reason-is-one-of-the-spec-reserved-closed-enum-values-or-matches-the-x-host-host',
209
211
  'RFCS/0032-envelope-reliability-events.md §B.1',
210
212
  'reason MUST be in the spec-reserved set OR match x-host-<host>-<key>',
211
213
  ),
@@ -213,17 +215,17 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: runtime behavior (RFC 0032
213
215
  });
214
216
 
215
217
  it('eventual success records normally via envelope acceptance + downstream RunEventDoc', async () => {
216
- if (!isFixtureAdvertised(FIXTURE)) return;
218
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
217
219
  const seed = await programMock([{ content: 'invalid' }, { content: '{"valid":true}' }]);
218
- if (seed.status === 404) return;
220
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
219
221
 
220
222
  const events = await startRunAndRead();
221
- if (events === null) return;
223
+ if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
222
224
  const nodeCompleted = events.find((e) => e.type === 'node.completed' && e.nodeId === NODE_ID);
223
225
  const runCompleted = events.find((e) => e.type === 'run.completed');
224
226
  expect(
225
227
  nodeCompleted,
226
- driver.describe(
228
+ req('openwop.it.envelope-retry-attempted.eventual-success-records-normally-via-envelope-acceptance-downstream-runeventdoc',
227
229
  'RFCS/0032-envelope-reliability-events.md §B.1',
228
230
  'eventual success MUST produce a node.completed for the dispatching node',
229
231
  ),
@@ -232,25 +234,25 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-attempted: runtime behavior (RFC 0032
232
234
  });
233
235
 
234
236
  it('`previousError` (when populated) MUST NOT contain prompt or response substring excerpts — limit to validator output', async () => {
235
- if (!isFixtureAdvertised(FIXTURE)) return;
237
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
236
238
  const PROMPT_CANARY = 'PROMPT-CANARY-RETRY-ATTEMPTED-DO-NOT-LEAK-' + Math.random().toString(36).slice(2, 10);
237
239
  const RESPONSE_CANARY = 'RESPONSE-CANARY-' + PROMPT_CANARY;
238
240
  const seed = await programMock([
239
241
  { content: `not valid json mentioning ${RESPONSE_CANARY}` },
240
242
  { content: '{"valid":true}' },
241
243
  ]);
242
- if (seed.status === 404) return;
244
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
243
245
 
244
246
  const events = await startRunAndRead();
245
- if (events === null) return;
247
+ if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
246
248
  const retry = events.find((e) => e.type === 'envelope.retry.attempted');
247
- if (!retry) return;
249
+ if (!retry) return softSkip('blocked', 'precondition not met — `!retry` returned early (seam, prior step, or fixture unavailable)');
248
250
  const previousError = retry.payload?.previousError;
249
- if (previousError === undefined || previousError === null) return; // field is optional
251
+ if (previousError === undefined || previousError === null) return softSkip('blocked', 'precondition not met — `previousError === undefined || previousError === null` returned early (field is optional) (seam, prior step, or fixture unavailable)'); // field is optional
250
252
  const serialized = typeof previousError === 'string' ? previousError : JSON.stringify(previousError);
251
253
  expect(
252
254
  serialized.includes(RESPONSE_CANARY),
253
- driver.describe(
255
+ req('openwop.it.envelope-retry-attempted.previouserror-when-populated-must-not-contain-prompt-or-response-substring-excer',
254
256
  'RFCS/0032-envelope-reliability-events.md §G',
255
257
  'previousError MUST NOT echo provider response substrings — validator output only',
256
258
  ),
@@ -28,6 +28,8 @@ import { describe, it, expect } from 'vitest';
28
28
  import { driver } from '../lib/driver.js';
29
29
  import { pollUntilTerminal } from '../lib/polling.js';
30
30
  import { isFixtureAdvertised } from '../lib/fixtures.js';
31
+ import { req } from '../lib/requirement-ids.js';
32
+ import { softSkip } from '../lib/soft-skip.js';
31
33
 
32
34
  const HTTP_SKIP = !process.env.OPENWOP_BASE_URL;
33
35
  const FIXTURE = 'conformance-envelope-retry-exhausted';
@@ -69,7 +71,7 @@ async function startRunAndRead(): Promise<{ events: RunEvent[]; terminal: unknow
69
71
 
70
72
  describe.skipIf(HTTP_SKIP)('envelope-retry-exhausted: runtime behavior (RFC 0032 §B.2 MUST)', () => {
71
73
  it('host exhausts retries with all-invalid program → exactly one envelope.retry.exhausted event', async () => {
72
- if (!isFixtureAdvertised(FIXTURE)) return;
74
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
73
75
  // Seed maxRetryAttempts entries of invalid JSON so dispatchStructured
74
76
  // hits every retry and then exhausts. The mock returns empty-stop
75
77
  // after program exhaustion, but dispatchStructured short-circuits
@@ -80,16 +82,16 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-exhausted: runtime behavior (RFC 0032
80
82
  { content: 'not json c' },
81
83
  { content: 'not json d' },
82
84
  ]);
83
- if (seed.status === 404) return;
85
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
84
86
  expect(seed.status).toBe(200);
85
87
 
86
88
  const result = await startRunAndRead();
87
- if (result === null) return;
89
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
88
90
  const { events } = result;
89
91
  const exhausted = events.filter((e) => e.type === 'envelope.retry.exhausted');
90
92
  expect(
91
93
  exhausted.length,
92
- driver.describe(
94
+ req('openwop.it.envelope-retry-exhausted.host-exhausts-retries-with-all-invalid-program-exactly-one-envelope-retry-exhaus',
93
95
  'RFCS/0032-envelope-reliability-events.md §B.2',
94
96
  'exactly one envelope.retry.exhausted event MUST fire on retry-budget exhaustion',
95
97
  ),
@@ -97,32 +99,32 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-exhausted: runtime behavior (RFC 0032
97
99
  });
98
100
 
99
101
  it('totalAttempts in payload matches the host advertised maxRetryAttempts', async () => {
100
- if (!isFixtureAdvertised(FIXTURE)) return;
102
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
101
103
  const seed = await programMock([{ content: 'x' }, { content: 'y' }, { content: 'z' }, { content: 'w' }]);
102
- if (seed.status === 404) return;
104
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
103
105
 
104
106
  const result = await startRunAndRead();
105
- if (result === null) return;
107
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
106
108
  const exhausted = result.events.find((e) => e.type === 'envelope.retry.exhausted');
107
- expect(exhausted).toBeDefined();
109
+ expect(exhausted, req('openwop.it.envelope-retry-exhausted.totalattempts-in-payload-matches-the-host-advertised-maxretryattempts', 'RFC 0032 §B.2', 'totalAttempts in payload matches the host advertised maxRetryAttempts')).toBeDefined();
108
110
  const total = exhausted!.payload?.totalAttempts;
109
111
  expect(typeof total === 'number' && (total as number) >= 1).toBe(true);
110
112
  });
111
113
 
112
114
  it('finalReason is in the spec-reserved enum OR matches x-host-<host>-<key>', async () => {
113
- if (!isFixtureAdvertised(FIXTURE)) return;
115
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
114
116
  const seed = await programMock([{ content: 'x' }, { content: 'y' }, { content: 'z' }, { content: 'w' }]);
115
- if (seed.status === 404) return;
117
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
116
118
 
117
119
  const result = await startRunAndRead();
118
- if (result === null) return;
120
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
119
121
  const exhausted = result.events.find((e) => e.type === 'envelope.retry.exhausted');
120
122
  expect(exhausted).toBeDefined();
121
123
  const reason = exhausted!.payload?.finalReason;
122
124
  expect(typeof reason).toBe('string');
123
125
  expect(
124
126
  RFC_0032_REASONS.has(reason as string) || HOST_REASON_EXT_RE.test(reason as string),
125
- driver.describe(
127
+ req('openwop.it.envelope-retry-exhausted.finalreason-is-in-the-spec-reserved-enum-or-matches-x-host-host-key',
126
128
  'RFCS/0032-envelope-reliability-events.md §B.2',
127
129
  'finalReason MUST be in the spec-reserved set OR match x-host-<host>-<key>',
128
130
  ),
@@ -130,16 +132,16 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-exhausted: runtime behavior (RFC 0032
130
132
  });
131
133
 
132
134
  it('RunSnapshot.error.code is envelope_invalid for schema-violation exhaustion (RFC 0033 §C)', async () => {
133
- if (!isFixtureAdvertised(FIXTURE)) return;
135
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
134
136
  const seed = await programMock([{ content: 'x' }, { content: 'y' }, { content: 'z' }, { content: 'w' }]);
135
- if (seed.status === 404) return;
137
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
136
138
 
137
139
  const result = await startRunAndRead();
138
- if (result === null) return;
140
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
139
141
  const code = (result.terminal as { error?: { code?: string } }).error?.code;
140
142
  expect(
141
143
  code,
142
- driver.describe(
144
+ req('openwop.it.envelope-retry-exhausted.runsnapshot-error-code-is-envelope-invalid-for-schema-violation-exhaustion-rfc-0',
143
145
  'RFCS/0033-envelope-completion-contract.md §C',
144
146
  'schema-violation-exhaustion MUST surface as RunSnapshot.error.code = envelope_invalid',
145
147
  ),
@@ -147,19 +149,19 @@ describe.skipIf(HTTP_SKIP)('envelope-retry-exhausted: runtime behavior (RFC 0032
147
149
  });
148
150
 
149
151
  it('envelope.retry.exhausted is emitted BEFORE node.failed (cause precedes effect)', async () => {
150
- if (!isFixtureAdvertised(FIXTURE)) return;
152
+ if (!isFixtureAdvertised(FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(FIXTURE)` returned early');
151
153
  const seed = await programMock([{ content: 'x' }, { content: 'y' }, { content: 'z' }, { content: 'w' }]);
152
- if (seed.status === 404) return;
154
+ if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
153
155
 
154
156
  const result = await startRunAndRead();
155
- if (result === null) return;
157
+ if (result === null) return softSkip('blocked', 'precondition not met — `result === null` returned early (seam, prior step, or fixture unavailable)');
156
158
  const exhaustedIdx = result.events.findIndex((e) => e.type === 'envelope.retry.exhausted');
157
159
  const failedIdx = result.events.findIndex((e) => e.type === 'node.failed');
158
160
  expect(exhaustedIdx).toBeGreaterThanOrEqual(0);
159
161
  expect(failedIdx).toBeGreaterThanOrEqual(0);
160
162
  expect(
161
163
  exhaustedIdx < failedIdx,
162
- driver.describe(
164
+ req('openwop.it.envelope-retry-exhausted.envelope-retry-exhausted-is-emitted-before-node-failed-cause-precedes-effect',
163
165
  'RFCS/0032-envelope-reliability-events.md §B.2',
164
166
  'envelope.retry.exhausted MUST be emitted BEFORE node.failed (the event signals the host is about to surface the terminal failure)',
165
167
  ),
@@ -35,6 +35,8 @@ import { join } from 'node:path';
35
35
  import { driver } from '../lib/driver.js';
36
36
  import { SCHEMAS_DIR } from '../lib/paths.js';
37
37
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
38
+ import { req } from '../lib/requirement-ids.js';
39
+ import { softSkip } from '../lib/soft-skip.js';
38
40
 
39
41
  const HTTP_SKIP = !process.env.OPENWOP_BASE_URL;
40
42
 
@@ -179,11 +181,11 @@ function walkSchema(
179
181
  describe.skipIf(HTTP_SKIP)('envelope-tier-one-subset-static (RFC 0030 §B)', () => {
180
182
  it('hosts advertising tierOneSubsetCompliance: "strict" have payload schemas that satisfy the Tier-1 intersection', async () => {
181
183
  const d = await readDiscovery();
182
- if (d === null) return; // host unreachable; soft-skip
184
+ if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (host unreachable; soft-skip) (seam, prior step, or fixture unavailable)'); // host unreachable; soft-skip
183
185
  const compliance = capabilityFamily(d, 'envelopes')?.tierOneSubsetCompliance;
184
- if (compliance !== 'strict') return; // gated on "strict" only
186
+ if (compliance !== 'strict') return softSkip('blocked', 'precondition not met — `compliance !== \'strict\'` returned early (gated on "strict" only) (seam, prior step, or fixture unavailable)'); // gated on "strict" only
185
187
  const advertised = (capabilityFamily(d, 'supportedEnvelopes') ?? []) as string[];
186
- if (advertised.length === 0) return;
188
+ if (advertised.length === 0) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `advertised.length === 0` returned early');
187
189
 
188
190
  const violationsByKind: Record<string, Violation[]> = {};
189
191
  for (const kind of advertised) {
@@ -202,7 +204,7 @@ describe.skipIf(HTTP_SKIP)('envelope-tier-one-subset-static (RFC 0030 §B)', ()
202
204
 
203
205
  expect(
204
206
  violationsByKind,
205
- `RFC 0030 §B: schemas violating the Tier-1 subset under strict-mode advertisement: ${JSON.stringify(violationsByKind, null, 2)}`,
207
+ req('openwop.it.envelope-tier-one-subset-static.hosts-advertising-tieronesubsetcompliance-strict-have-payload-schemas-that-satis', 'RFC 0030 §B', `RFC 0030 §B: schemas violating the Tier-1 subset under strict-mode advertisement: ${JSON.stringify(violationsByKind, null, 2)}`),
206
208
  ).toEqual({});
207
209
  });
208
210
  });
@@ -216,14 +218,14 @@ describe('envelope-tier-one-subset-static: universal-kind schemas satisfy load-b
216
218
  for (const kind of UNIVERSAL_KINDS) {
217
219
  it(`${kind}.schema.json satisfies load-bearing Tier-1 rules (no oneOf/allOf/not/prefixItems/propertyNames anywhere)`, () => {
218
220
  const schema = loadLocalSchema(kind);
219
- expect(schema, `schemas/envelopes/${kind}.schema.json MUST exist`).not.toBeNull();
220
- if (schema === null) return;
221
+ expect(schema, req('openwop.it.envelope-tier-one-subset-static.schema-json-satisfies-load-bearing-tier-1-rules-no-oneof-allof-not-prefixitems-p', 'RFC 0030 §B', `schemas/envelopes/${kind}.schema.json MUST exist`)).not.toBeNull();
222
+ if (schema === null) return softSkip('blocked', 'precondition not met — `schema === null` returned early (seam, prior step, or fixture unavailable)');
221
223
  const violations: Violation[] = [];
222
224
  const propCount = { n: 0 };
223
225
  walkSchema(schema, `#`, 0, propCount, violations, 'load-bearing');
224
226
  expect(
225
227
  violations,
226
- `${kind}.schema.json load-bearing Tier-1 violations (these fail across multiple vendors): ${JSON.stringify(violations, null, 2)}`,
228
+ req('openwop.it.envelope-tier-one-subset-static.schema-json-satisfies-load-bearing-tier-1-rules-no-oneof-allof-not-prefixitems-p', 'RFC 0030 §B', `${kind}.schema.json load-bearing Tier-1 violations (these fail across multiple vendors): ${JSON.stringify(violations, null, 2)}`),
227
229
  ).toEqual([]);
228
230
  });
229
231
  }