@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
@@ -11,8 +11,8 @@
11
11
 
12
12
  import { describe, it, expect } from 'vitest';
13
13
  import { softSkip } from '../lib/soft-skip.js';
14
- import { driver } from '../lib/driver.js';
15
14
  import { readSubRunAttestationCap, invokeSubRunAttest } from '../lib/subRunAttestation.js';
15
+ import { req } from '../lib/requirement-ids.js';
16
16
 
17
17
  describe('subrun-approval-gate (RFC 0063 §C)', () => {
18
18
  it('accept merges the child outputs; reject does not', async () => {
@@ -23,14 +23,14 @@ describe('subrun-approval-gate (RFC 0063 §C)', () => {
23
23
  if (accepted === null) return softSkip('blocked', 'seam absent — soft-skip');
24
24
  expect(
25
25
  accepted.merged,
26
- driver.describe('RFC 0063 §C', 'an `accept` approval MUST merge the child outputs'),
26
+ req('openwop.it.subrun-approval-gate.accept-merges-the-child-outputs-reject-does-not', 'RFC 0063 §C', 'an `accept` approval MUST merge the child outputs'),
27
27
  ).toBe(true);
28
28
 
29
29
  const rejected = await invokeSubRunAttest({ ...base, approvalAction: 'reject' });
30
30
  if (rejected === null) return softSkip('blocked', 'precondition not met — `rejected === null` returned early (seam, prior step, or fixture unavailable)');
31
31
  expect(
32
32
  rejected.merged,
33
- driver.describe('RFC 0063 §C', 'a `reject` approval MUST NOT merge the child outputs'),
33
+ req('openwop.it.subrun-approval-gate.accept-merges-the-child-outputs-reject-does-not', 'RFC 0063 §C', 'a `reject` approval MUST NOT merge the child outputs'),
34
34
  ).toBe(false);
35
35
  });
36
36
  });
@@ -12,8 +12,8 @@
12
12
 
13
13
  import { describe, it, expect } from 'vitest';
14
14
  import { softSkip } from '../lib/soft-skip.js';
15
- import { driver } from '../lib/driver.js';
16
15
  import { readSubRunAttestationCap } from '../lib/subRunAttestation.js';
16
+ import { req } from '../lib/requirement-ids.js';
17
17
 
18
18
  describe('subrun-attestation-shape: advertisement (RFC 0063 §A)', () => {
19
19
  it('capabilities.agents.subRunAttestation is absent or a boolean', async () => {
@@ -22,7 +22,7 @@ describe('subrun-attestation-shape: advertisement (RFC 0063 §A)', () => {
22
22
  if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early');
23
23
  expect(
24
24
  typeof cap,
25
- driver.describe(
25
+ req('openwop.it.subrun-attestation-shape.capabilities-agents-subrunattestation-is-absent-or-a-boolean',
26
26
  'capabilities.schema.json §agents.subRunAttestation',
27
27
  'agents.subRunAttestation MUST be a boolean when present',
28
28
  ),
@@ -12,8 +12,8 @@
12
12
 
13
13
  import { describe, it, expect } from 'vitest';
14
14
  import { softSkip } from '../lib/soft-skip.js';
15
- import { driver } from '../lib/driver.js';
16
15
  import { readSubRunAttestationCap, invokeSubRunAttest } from '../lib/subRunAttestation.js';
16
+ import { req } from '../lib/requirement-ids.js';
17
17
 
18
18
  describe('subrun-checksum-stable (RFC 0063 §B)', () => {
19
19
  it('identical child outputs produce an identical sha256 attestation checksum', async () => {
@@ -30,15 +30,15 @@ describe('subrun-checksum-stable (RFC 0063 §B)', () => {
30
30
  const att = a.attestation ?? {};
31
31
  expect(
32
32
  typeof att.checksum === 'string' && (att.checksum as string).length > 0,
33
- driver.describe('RFC 0063 §B', 'output.harvested MUST carry a non-empty attestation.checksum when checksum:true'),
33
+ req('openwop.it.subrun-checksum-stable.identical-child-outputs-produce-an-identical-sha256-attestation-checksum', 'RFC 0063 §B', 'output.harvested MUST carry a non-empty attestation.checksum when checksum:true'),
34
34
  ).toBe(true);
35
35
  expect(
36
36
  att.algorithm,
37
- driver.describe('RFC 0063 §B', 'attestation.algorithm MUST be "sha256" (the v1 recipe)'),
37
+ req('openwop.it.subrun-checksum-stable.identical-child-outputs-produce-an-identical-sha256-attestation-checksum', 'RFC 0063 §B', 'attestation.algorithm MUST be "sha256" (the v1 recipe)'),
38
38
  ).toBe('sha256');
39
39
  expect(
40
40
  (b.attestation ?? {}).checksum,
41
- driver.describe('RFC 0063 §B', 'JCS canonicalization MUST make the checksum invariant to key order — same content, same hash'),
41
+ req('openwop.it.subrun-checksum-stable.identical-child-outputs-produce-an-identical-sha256-attestation-checksum', 'RFC 0063 §B', 'JCS canonicalization MUST make the checksum invariant to key order — same content, same hash'),
42
42
  ).toBe(att.checksum);
43
43
  });
44
44
  });
@@ -23,6 +23,8 @@ import { driver } from '../lib/driver.js';
23
23
  import { pollUntilTerminal, pollUntilStatus } from '../lib/polling.js';
24
24
  import { isFixtureAdvertised } from '../lib/fixtures.js';
25
25
  import { setHostCapability, resetHostCapabilities, isToggleAvailable } from '../lib/host-toggle.js';
26
+ import { req } from '../lib/requirement-ids.js';
27
+ import { softSkip } from '../lib/soft-skip.js';
26
28
 
27
29
  const PARENT = 'conformance-subworkflow-input-mapping';
28
30
  const CHILD = 'conformance-subworkflow-input-mapping-child';
@@ -51,7 +53,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
51
53
  const parentRunId = (create.json as { runId: string }).runId;
52
54
 
53
55
  const parentTerminal = (await pollUntilTerminal(parentRunId)) as RunSnapshot;
54
- expect(parentTerminal.status, driver.describe(
56
+ expect(parentTerminal.status, req('openwop.it.subworkflow-input-mapping.hvmap-2-inputmapping-seeds-child-variables-overrides-defaultvalue-child-reads-pa',
55
57
  'RFCS/0022-dispatch-input-output-mapping.md §B',
56
58
  'parent run MUST reach terminal `completed` once the child finishes',
57
59
  )).toBe('completed');
@@ -63,7 +65,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
63
65
  const subwfCompleted = events.find(
64
66
  (e) => e.type === 'node.completed' && e.nodeId === 'subwf-call',
65
67
  );
66
- expect(subwfCompleted, driver.describe(
68
+ expect(subwfCompleted, req('openwop.it.subworkflow-input-mapping.hvmap-2-inputmapping-seeds-child-variables-overrides-defaultvalue-child-reads-pa',
67
69
  'spec/v1/node-packs.md §"`core.subWorkflow` contract"',
68
70
  'parent event log MUST contain `node.completed` for the subwf-call node',
69
71
  )).toBeDefined();
@@ -76,12 +78,12 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
76
78
  const childSnapshotRes = await driver.get(`/v1/runs/${encodeURIComponent(childRunId!)}`);
77
79
  expect(childSnapshotRes.status).toBe(200);
78
80
  const childSnapshot = childSnapshotRes.json as RunSnapshot;
79
- expect(childSnapshot.status, driver.describe(
81
+ expect(childSnapshot.status, req('openwop.it.subworkflow-input-mapping.hvmap-2-inputmapping-seeds-child-variables-overrides-defaultvalue-child-reads-pa',
80
82
  'spec/v1/node-packs.md §"`core.subWorkflow` contract"',
81
83
  'child run MUST reach terminal `completed`',
82
84
  )).toBe('completed');
83
85
  const childVars = childSnapshot.variables ?? {};
84
- expect(childVars.receivedPrdId, driver.describe(
86
+ expect(childVars.receivedPrdId, req('openwop.it.subworkflow-input-mapping.hvmap-2-inputmapping-seeds-child-variables-overrides-defaultvalue-child-reads-pa',
85
87
  'RFCS/0022-dispatch-input-output-mapping.md §B',
86
88
  'child `receivedPrdId` MUST be parent\'s `currentPrdId` projection ("prd-1"), overriding the child\'s defaultValue "baked-in"',
87
89
  )).toBe('prd-1');
@@ -89,7 +91,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
89
91
 
90
92
  it('HVMAP-2-unset: parent.currentPrdId unset → child receivedPrdId MUST surface as `undefined`', async () => {
91
93
  const PARENT_NO_DEFAULT = 'conformance-subworkflow-input-mapping-no-default';
92
- if (!isFixtureAdvertised(PARENT_NO_DEFAULT) || !isFixtureAdvertised(CHILD)) return; // soft-skip
94
+ if (!isFixtureAdvertised(PARENT_NO_DEFAULT) || !isFixtureAdvertised(CHILD)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(PARENT_NO_DEFAULT) || !isFixtureAdvertised(CHILD)` returned early (soft-skip)'); // soft-skip
93
95
  const create = await driver.post('/v1/runs', { workflowId: PARENT_NO_DEFAULT });
94
96
  expect(create.status).toBe(201);
95
97
  const parentRunId = (create.json as { runId: string }).runId;
@@ -100,7 +102,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
100
102
  const subwfCompleted = events.find(
101
103
  (e) => e.type === 'node.completed' && e.nodeId === 'subwf-call',
102
104
  );
103
- if (!subwfCompleted) return;
105
+ if (!subwfCompleted) return softSkip('blocked', 'precondition not met — `!subwfCompleted` returned early (seam, prior step, or fixture unavailable)');
104
106
  const childRunId = subwfCompleted.payload?.outputs?.childRunId;
105
107
 
106
108
  const childRes = await driver.get(`/v1/runs/${encodeURIComponent(childRunId!)}`);
@@ -114,7 +116,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
114
116
  // undefined the child's defaultValue should remain.
115
117
  expect(
116
118
  v === 'baked-in' || v === undefined || !('receivedPrdId' in vars),
117
- driver.describe(
119
+ req('openwop.it.subworkflow-input-mapping.hvmap-2-unset-parent-currentprdid-unset-child-receivedprdid-must-surface-as-unde',
118
120
  'RFCS/0022-dispatch-input-output-mapping.md §B',
119
121
  'unset parent variable MUST surface as undefined-or-defaultValue-fallback (NOT null)',
120
122
  ),
@@ -137,8 +139,8 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
137
139
  const CHILD_GATE_NODE = 'child-gate';
138
140
 
139
141
  it('HVMAP-2-no-midrun-propagation: parent mid-run mutation MUST NOT propagate into the seeded child', async () => {
140
- if (!isFixtureAdvertised(MID_RUN_PARENT) || !isFixtureAdvertised(MID_RUN_CHILD)) return; // fixture not seeded — soft-skip
141
- if (!(await isToggleAvailable())) return; // sample test seam not exposed — soft-skip
142
+ if (!isFixtureAdvertised(MID_RUN_PARENT) || !isFixtureAdvertised(MID_RUN_CHILD)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(MID_RUN_PARENT) || !isFixtureAdvertised(MID_RUN_CHILD)` returned early (fixture not seeded — soft-skip)'); // fixture not seeded — soft-skip
143
+ if (!(await isToggleAvailable())) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!(await isToggleAvailable())` returned early (sample test seam not exposed — soft-skip)'); // sample test seam not exposed — soft-skip
142
144
 
143
145
  const create = await driver.post('/v1/runs', { workflowId: MID_RUN_PARENT });
144
146
  expect(create.status).toBe(201);
@@ -156,7 +158,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
156
158
  const parentSnap = await driver.get(`/v1/runs/${encodeURIComponent(parentRunId)}`);
157
159
  const parentJson = parentSnap.json as { childRuns?: Array<{ runId: string; status: string }> };
158
160
  const childRunId = parentJson.childRuns?.[0]?.runId;
159
- expect(childRunId, driver.describe(
161
+ expect(childRunId, req('openwop.it.subworkflow-input-mapping.hvmap-2-no-midrun-propagation-parent-mid-run-mutation-must-not-propagate-into-th',
160
162
  'fixtures.md conformance-subworkflow-mid-run-mutation',
161
163
  'parent snapshot MUST surface the spawned child runId via childRuns[]',
162
164
  )).toBeDefined();
@@ -185,7 +187,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
185
187
  // (`seeded-id`), NOT the post-mutation parent value (`mutated-id`).
186
188
  expect(
187
189
  childTerminal.variables?.receivedPrdId,
188
- driver.describe(
190
+ req('openwop.it.subworkflow-input-mapping.hvmap-2-no-midrun-propagation-parent-mid-run-mutation-must-not-propagate-into-th',
189
191
  'RFCS/0022-dispatch-input-output-mapping.md §B',
190
192
  'mid-run parent mutation MUST NOT propagate; child receivedPrdId stays at dispatch-time fold',
191
193
  ),
@@ -196,7 +198,7 @@ describe.skipIf(SKIP)('subworkflow-input-mapping: parent → child variable seed
196
198
 
197
199
  describe('subworkflow-input-mapping: registration refusal (RFC 0022 §C HVMAP-2-refusal)', () => {
198
200
  it('host with subWorkflow.inputMapping toggled OFF MUST refuse non-empty inputMapping at registration', async () => {
199
- if (!(await isToggleAvailable())) return; // seam not exposed — soft-skip
201
+ if (!(await isToggleAvailable())) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!(await isToggleAvailable())` returned early (seam not exposed — soft-skip)'); // seam not exposed — soft-skip
200
202
  await setHostCapability('subWorkflow.inputMapping', false);
201
203
  try {
202
204
  const workflow = {
@@ -215,7 +217,7 @@ describe('subworkflow-input-mapping: registration refusal (RFC 0022 §C HVMAP-2-
215
217
  const res = await driver.post('/v1/host/sample/workflows', workflow);
216
218
  expect(
217
219
  res.status,
218
- driver.describe(
220
+ req('openwop.it.subworkflow-input-mapping.host-with-subworkflow-inputmapping-toggled-off-must-refuse-non-empty-inputmappin',
219
221
  'RFCS/0022-dispatch-input-output-mapping.md §C',
220
222
  'workflow with non-empty subWorkflow.inputMapping MUST be refused when capability is not advertised',
221
223
  ),
@@ -224,7 +226,7 @@ describe('subworkflow-input-mapping: registration refusal (RFC 0022 §C HVMAP-2-
224
226
  expect(body.error).toBe('validation_error');
225
227
  expect(
226
228
  body.details?.requiredCapability,
227
- driver.describe(
229
+ req('openwop.it.subworkflow-input-mapping.host-with-subworkflow-inputmapping-toggled-off-must-refuse-non-empty-inputmappin',
228
230
  'RFCS/0022-dispatch-input-output-mapping.md §C',
229
231
  'refusal MUST surface requiredCapability: "subWorkflow.inputMapping"',
230
232
  ),
@@ -20,6 +20,7 @@ import { describe, it, expect } from 'vitest';
20
20
  import { driver } from '../lib/driver.js';
21
21
  import { pollUntilTerminal } from '../lib/polling.js';
22
22
  import { isFixtureAdvertised } from '../lib/fixtures.js';
23
+ import { req } from '../lib/requirement-ids.js';
23
24
 
24
25
  const PARENT_WORKFLOW_ID = 'conformance-subworkflow-parent';
25
26
  const CHILD_WORKFLOW_ID = 'conformance-subworkflow-child';
@@ -50,7 +51,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('subworkflow: conformance-subworkflow-parent di
50
51
  const parentRunId = (create.json as { runId: string }).runId;
51
52
 
52
53
  const parentTerminal = await pollUntilTerminal(parentRunId);
53
- expect(parentTerminal.status, driver.describe(
54
+ expect(parentTerminal.status, req('openwop.it.subworkflow.parent-run-reaches-terminal-completed-and-child-variable-is-propagated-via-outpu',
54
55
  'fixtures.md conformance-subworkflow-parent §Terminal status',
55
56
  'parent fixture MUST reach terminal `completed` after child finishes',
56
57
  )).toBe('completed');
@@ -59,7 +60,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('subworkflow: conformance-subworkflow-parent di
59
60
  // parent's `childOutcome`. The variable should appear on the parent's
60
61
  // final variables.
61
62
  const parentVars = (parentTerminal as RunSnapshot).variables ?? {};
62
- expect(parentVars.childOutcome, driver.describe(
63
+ expect(parentVars.childOutcome, req('openwop.it.subworkflow.parent-run-reaches-terminal-completed-and-child-variable-is-propagated-via-outpu',
63
64
  'node-packs.md §core.subWorkflow outputMapping',
64
65
  'parent variables MUST include `childOutcome` mapped from child `childResult`',
65
66
  )).toBeDefined();
@@ -84,7 +85,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('subworkflow: conformance-subworkflow-parent di
84
85
  const subwfCompleted = events.find(
85
86
  (e) => e.type === 'node.completed' && e.nodeId === 'subwf-call',
86
87
  );
87
- expect(subwfCompleted, driver.describe(
88
+ expect(subwfCompleted, req('openwop.it.subworkflow.child-run-is-created-with-parent-linkage-fields-and-reaches-terminal-completed',
88
89
  'node-packs.md §core.subWorkflow',
89
90
  'parent event log MUST contain node.completed for the subwf-call node',
90
91
  )).toBeDefined();
@@ -93,32 +94,32 @@ describe.skipIf(SKIP_NO_FIXTURE)('subworkflow: conformance-subworkflow-parent di
93
94
  | { outputs?: { childRunId?: string; childStatus?: string; skipped?: boolean } }
94
95
  | undefined;
95
96
  const childRunId = subwfPayload?.outputs?.childRunId;
96
- expect(typeof childRunId, driver.describe(
97
+ expect(typeof childRunId, req('openwop.it.subworkflow.child-run-is-created-with-parent-linkage-fields-and-reaches-terminal-completed',
97
98
  'node-packs.md §core.subWorkflow outputSchema',
98
99
  'core.subWorkflow output MUST include childRunId as a string',
99
100
  )).toBe('string');
100
101
 
101
- expect(subwfPayload?.outputs?.childStatus, driver.describe(
102
+ expect(subwfPayload?.outputs?.childStatus, req('openwop.it.subworkflow.child-run-is-created-with-parent-linkage-fields-and-reaches-terminal-completed',
102
103
  'node-packs.md §core.subWorkflow outputSchema',
103
104
  'core.subWorkflow output MUST include childStatus="completed" on success',
104
105
  )).toBe('completed');
105
106
 
106
107
  // Fetch the child run snapshot and verify parent linkage.
107
108
  const childRes = await driver.get(`/v1/runs/${encodeURIComponent(childRunId!)}`);
108
- expect(childRes.status, 'child run snapshot MUST be retrievable').toBe(200);
109
+ expect(childRes.status, req('openwop.it.subworkflow.child-run-is-created-with-parent-linkage-fields-and-reaches-terminal-completed', 'node-packs.md §core.subWorkflow outputSchema', 'child run snapshot MUST be retrievable')).toBe(200);
109
110
  const child = childRes.json as RunSnapshot;
110
111
 
111
- expect(child.status, driver.describe(
112
+ expect(child.status, req('openwop.it.subworkflow.child-run-is-created-with-parent-linkage-fields-and-reaches-terminal-completed',
112
113
  'fixtures.md conformance-subworkflow-child §Terminal status',
113
114
  'child MUST reach terminal `completed`',
114
115
  )).toBe('completed');
115
116
 
116
- expect(child.parentRunId, driver.describe(
117
+ expect(child.parentRunId, req('openwop.it.subworkflow.child-run-is-created-with-parent-linkage-fields-and-reaches-terminal-completed',
117
118
  'spec gap G3 parent linkage',
118
119
  'child run MUST carry parentRunId pointing back to dispatcher',
119
120
  )).toBe(parentRunId);
120
121
 
121
- expect(child.parentNodeId, driver.describe(
122
+ expect(child.parentNodeId, req('openwop.it.subworkflow.child-run-is-created-with-parent-linkage-fields-and-reaches-terminal-completed',
122
123
  'spec gap G3 parent linkage',
123
124
  'child run MUST carry parentNodeId pointing back to the subwf-call node',
124
125
  )).toBe('subwf-call');
@@ -11,6 +11,8 @@
11
11
  import { describe, it, expect } from 'vitest';
12
12
  import { driver } from '../lib/driver.js';
13
13
  import { discoveryFamilies } from '../lib/discovery-capabilities.js';
14
+ import { req } from '../lib/requirement-ids.js';
15
+ import { softSkip } from '../lib/soft-skip.js';
14
16
 
15
17
  interface DiscoveryDoc {
16
18
  capabilities?: Record<string, unknown>;
@@ -31,10 +33,10 @@ async function call(tenantId: string, op: string, args: Record<string, unknown>)
31
33
  describe('table-cross-tenant-isolation: advertisement shape (RFC 0016)', () => {
32
34
  it('capabilities.tableStorage is either absent or a well-formed object', async () => {
33
35
  const cap = await readCap();
34
- if (cap === null) return;
36
+ if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early');
35
37
  expect(
36
38
  typeof cap.supported,
37
- driver.describe(
39
+ req('openwop.it.table-cross-tenant-isolation.capabilities-tablestorage-is-either-absent-or-a-well-formed-object',
38
40
  'capabilities.schema.json §tableStorage',
39
41
  'capabilities.tableStorage.supported MUST be a boolean when present',
40
42
  ),
@@ -45,22 +47,22 @@ describe('table-cross-tenant-isolation: advertisement shape (RFC 0016)', () => {
45
47
  describe('table-cross-tenant-isolation: behavioral (RFC 0016 §B point 1)', () => {
46
48
  it('insert under tenant A → query under tenant B returns 0 rows', async () => {
47
49
  const cap = await readCap();
48
- if (!cap || cap.supported !== true) return;
50
+ if (!cap || cap.supported !== true) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!cap || cap.supported !== true` returned early');
49
51
  const table = `xtenant_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`;
50
52
 
51
53
  const insertRes = await call('tenant-a', 'insert', {
52
54
  table,
53
55
  row: { id: 'r1', body: 'from-A' },
54
56
  });
55
- if (insertRes.status === 404) return; // seam not exposed
56
- expect(insertRes.status, 'insert MUST succeed').toBe(200);
57
+ if (insertRes.status === 404) return softSkip('blocked', 'precondition not met — `insertRes.status === 404` returned early (seam not exposed) (seam, prior step, or fixture unavailable)'); // seam not exposed
58
+ expect(insertRes.status, req('openwop.it.table-cross-tenant-isolation.insert-under-tenant-a-query-under-tenant-b-returns-0-rows', 'RFC 0016 §B point 1', 'insert MUST succeed')).toBe(200);
57
59
 
58
60
  const queryRes = await call('tenant-b', 'query', { table, filter: {} });
59
61
  expect(queryRes.status).toBe(200);
60
62
  const body = queryRes.json as { rows?: unknown[] };
61
63
  expect(
62
64
  Array.isArray(body.rows) ? body.rows.length : -1,
63
- driver.describe('RFC 0016 §B point 1', 'tenant B MUST see 0 rows in tenant A table'),
65
+ req('openwop.it.table-cross-tenant-isolation.insert-under-tenant-a-query-under-tenant-b-returns-0-rows', 'RFC 0016 §B point 1', 'tenant B MUST see 0 rows in tenant A table'),
64
66
  ).toBe(0);
65
67
  });
66
68
  });
@@ -16,6 +16,8 @@
16
16
  import { describe, it, expect } from 'vitest';
17
17
  import { driver } from '../lib/driver.js';
18
18
  import { discoveryFamilies } from '../lib/discovery-capabilities.js';
19
+ import { req } from '../lib/requirement-ids.js';
20
+ import { softSkip } from '../lib/soft-skip.js';
19
21
 
20
22
  interface DiscoveryDoc {
21
23
  capabilities?: Record<string, unknown>;
@@ -32,10 +34,10 @@ async function readCap(): Promise<Record<string, unknown> | null> {
32
34
  describe('table-cursor-pagination: advertisement shape (RFC 0016)', () => {
33
35
  it('capabilities.tableStorage is either absent or a well-formed object', async () => {
34
36
  const cap = await readCap();
35
- if (cap === null) return; // host doesn't advertise — skip
37
+ if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early (host doesn\'t advertise — skip)'); // host doesn't advertise — skip
36
38
  expect(
37
39
  typeof cap.supported,
38
- driver.describe(
40
+ req('openwop.it.table-cursor-pagination.capabilities-tablestorage-is-either-absent-or-a-well-formed-object',
39
41
  'capabilities.schema.json §tableStorage',
40
42
  'capabilities.tableStorage.supported MUST be a boolean when present',
41
43
  ),
@@ -50,7 +52,7 @@ async function call(op: string, args: Record<string, unknown>) {
50
52
  describe('table-cursor-pagination: behavioral (RFC 0016 §B point 3)', () => {
51
53
  it('first page returns N rows + nextCursor; second page resumes; final page returns nextCursor:null', async () => {
52
54
  const probe = await call('query', { table: '__probe__', limit: 1 });
53
- if (probe.status === 404) return; // seam not exposed
55
+ if (probe.status === 404) return softSkip('blocked', 'precondition not met — `probe.status === 404` returned early (seam not exposed) (seam, prior step, or fixture unavailable)'); // seam not exposed
54
56
  const table = `pag-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
55
57
  // Seed 5 rows with deterministic ids so cursor ordering is testable.
56
58
  for (let i = 1; i <= 5; i++) {
@@ -62,7 +64,7 @@ describe('table-cursor-pagination: behavioral (RFC 0016 §B point 3)', () => {
62
64
  expect(Array.isArray(b1.rows) && b1.rows.length === 2).toBe(true);
63
65
  expect(
64
66
  typeof b1.nextCursor === 'string' && b1.nextCursor.length > 0,
65
- driver.describe('RFC 0016 §B point 3', 'first page MUST surface nextCursor when more results remain'),
67
+ req('openwop.it.table-cursor-pagination.first-page-returns-n-rows-nextcursor-second-page-resumes-final-page-returns-next', 'RFC 0016 §B point 3', 'first page MUST surface nextCursor when more results remain'),
66
68
  ).toBe(true);
67
69
 
68
70
  // Page 2: cursor from page 1, limit=2
@@ -71,7 +73,7 @@ describe('table-cursor-pagination: behavioral (RFC 0016 §B point 3)', () => {
71
73
  expect(b2.rows?.length).toBe(2);
72
74
  expect(
73
75
  b2.rows![0]!.id > b1.rows![1]!.id,
74
- driver.describe('RFC 0016 §B point 3', 'second page MUST resume AFTER the last id of the previous page'),
76
+ req('openwop.it.table-cursor-pagination.first-page-returns-n-rows-nextcursor-second-page-resumes-final-page-returns-next', 'RFC 0016 §B point 3', 'second page MUST resume AFTER the last id of the previous page'),
75
77
  ).toBe(true);
76
78
 
77
79
  // Page 3: final page — only 1 row left, nextCursor MUST be null
@@ -80,7 +82,7 @@ describe('table-cursor-pagination: behavioral (RFC 0016 §B point 3)', () => {
80
82
  expect(b3.rows?.length).toBe(1);
81
83
  expect(
82
84
  b3.nextCursor,
83
- driver.describe('RFC 0016 §B point 3', 'final page (no more results) MUST surface nextCursor: null'),
85
+ req('openwop.it.table-cursor-pagination.first-page-returns-n-rows-nextcursor-second-page-resumes-final-page-returns-next', 'RFC 0016 §B point 3', 'final page (no more results) MUST surface nextCursor: null'),
84
86
  ).toBe(null);
85
87
  });
86
88
  });
@@ -17,6 +17,8 @@ import { describe, it, expect } from 'vitest';
17
17
  import { readErrorCode } from '../lib/error-envelope.js';
18
18
  import { driver } from '../lib/driver.js';
19
19
  import { discoveryFamilies } from '../lib/discovery-capabilities.js';
20
+ import { req } from '../lib/requirement-ids.js';
21
+ import { softSkip } from '../lib/soft-skip.js';
20
22
 
21
23
  interface DiscoveryDoc {
22
24
  capabilities?: Record<string, unknown>;
@@ -33,10 +35,10 @@ async function readCap(): Promise<Record<string, unknown> | null> {
33
35
  describe('table-schema-enforcement: advertisement shape (RFC 0016)', () => {
34
36
  it('capabilities.tableStorage is either absent or a well-formed object', async () => {
35
37
  const cap = await readCap();
36
- if (cap === null) return; // host doesn't advertise — skip
38
+ if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early (host doesn\'t advertise — skip)'); // host doesn't advertise — skip
37
39
  expect(
38
40
  typeof cap.supported,
39
- driver.describe(
41
+ req('openwop.it.table-schema-enforcement.capabilities-tablestorage-is-either-absent-or-a-well-formed-object',
40
42
  'capabilities.schema.json §tableStorage',
41
43
  'capabilities.tableStorage.supported MUST be a boolean when present',
42
44
  ),
@@ -51,7 +53,7 @@ async function call(op: string, args: Record<string, unknown>) {
51
53
  describe('table-schema-enforcement: behavioral (RFC 0016 §B point 2)', () => {
52
54
  it('first insert declares schema; subsequent insert with wrong column type is rejected', async () => {
53
55
  const probe = await call('insert', { table: '__probe__', row: { id: 'probe-0' } });
54
- if (probe.status === 404) return; // seam not exposed
56
+ if (probe.status === 404) return softSkip('blocked', 'precondition not met — `probe.status === 404` returned early (seam not exposed) (seam, prior step, or fixture unavailable)'); // seam not exposed
55
57
  const table = `sch-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
56
58
  // First insert — declares the schema from this row's columns.
57
59
  const first = await call('insert', {
@@ -74,12 +76,12 @@ describe('table-schema-enforcement: behavioral (RFC 0016 §B point 2)', () => {
74
76
  });
75
77
  expect(
76
78
  bad.status >= 400 && bad.status < 500,
77
- driver.describe('RFC 0016 §B point 2', 'type-divergent insert MUST be rejected with 4xx'),
79
+ req('openwop.it.table-schema-enforcement.first-insert-declares-schema-subsequent-insert-with-wrong-column-type-is-rejecte', 'RFC 0016 §B point 2', 'type-divergent insert MUST be rejected with 4xx'),
78
80
  ).toBe(true);
79
81
  const code = readErrorCode(bad.json);
80
82
  expect(
81
83
  code,
82
- driver.describe('RFC 0016 §B point 2', 'rejection MUST carry the table_schema_violation error code'),
84
+ req('openwop.it.table-schema-enforcement.first-insert-declares-schema-subsequent-insert-with-wrong-column-type-is-rejecte', 'RFC 0016 §B point 2', 'rejection MUST carry the table_schema_violation error code'),
83
85
  ).toBe('table_schema_violation');
84
86
  });
85
87
  });
@@ -49,8 +49,8 @@
49
49
  */
50
50
 
51
51
  import { describe, it, expect } from 'vitest';
52
- import { driver } from '../lib/driver.js';
53
52
  import { loadEnv } from '../lib/env.js';
53
+ import { req } from '../lib/requirement-ids.js';
54
54
 
55
55
  /**
56
56
  * Canonical seam paths from `host-sample-test-seams.md`. A host that exposes
@@ -160,7 +160,7 @@ describe('test-seam-unauthenticated: an enabled seam still authenticates', () =>
160
160
 
161
161
  expect(
162
162
  answered,
163
- driver.describe('host-sample-test-seams.md §"Production safety (normative)"', `${diagnosis}\n ${answered.join('\n ')}`),
163
+ req('openwop.it.test-seam-unauthenticated.no-v1-host-sample-seam-answers-an-unauthenticated-request-with-200', 'host-sample-test-seams.md §"Production safety (normative)"', `${diagnosis}\n ${answered.join('\n ')}`),
164
164
  ).toEqual([]);
165
165
  });
166
166
  });
@@ -46,6 +46,8 @@ import {
46
46
  findBannedInputSchemaKeyword,
47
47
  type CompactToolDescriptor,
48
48
  } from '../lib/toolCatalog.js';
49
+ import { req } from '../lib/requirement-ids.js';
50
+ import { softSkip } from '../lib/soft-skip.js';
49
51
 
50
52
  function loadSchema(name: string): Record<string, unknown> {
51
53
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -80,18 +82,18 @@ describe('tool-catalog-compact-projection (RFC 0112 §compact)', () => {
80
82
 
81
83
  // ---- Leg 1: the compact envelope (§compact) -------------------------
82
84
  const compact = await listToolsCompact();
83
- if (compact === null) return; // advertises the cap but doesn't serve the read — soft-skip the rest
85
+ if (compact === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `compact === null` returned early (advertises the cap but doesn\'t serve the read — soft-skip the rest)'); // advertises the cap but doesn't serve the read — soft-skip the rest
84
86
 
85
87
  for (const t of compact) {
86
88
  // ---- Leg 2: schema validity + heavy fields dropped ----------------
87
89
  expect(
88
90
  validate(t),
89
- driver.describe('compact-tool-descriptor.schema.json', `each CompactToolDescriptor MUST validate (${ajv.errorsText(validate.errors)})`),
91
+ req('openwop.it.tool-catalog-compact-projection.serves-the-tools-compacttooldescriptor-projection-closed-shape-bounded-inputsche', 'compact-tool-descriptor.schema.json', `each CompactToolDescriptor MUST validate (${ajv.errorsText(validate.errors)})`),
90
92
  ).toBe(true);
91
93
  for (const f of COMPACT_DROPPED_FIELDS) {
92
94
  expect(
93
95
  !(f in t),
94
- driver.describe('tool-catalog.md §compact', `CompactToolDescriptor MUST drop the heavy field "${f}"`),
96
+ req('openwop.it.tool-catalog-compact-projection.serves-the-tools-compacttooldescriptor-projection-closed-shape-bounded-inputsche', 'tool-catalog.md §compact', `CompactToolDescriptor MUST drop the heavy field "${f}"`),
95
97
  ).toBe(true);
96
98
  }
97
99
 
@@ -100,14 +102,14 @@ describe('tool-catalog-compact-projection (RFC 0112 §compact)', () => {
100
102
  if (input !== undefined) {
101
103
  expect(
102
104
  input.type === 'object' && typeof input.properties === 'object' && input.properties !== null,
103
- driver.describe('tool-catalog.md §compact', 'compact inputSchema MUST be top-level type:"object" with a properties map'),
105
+ req('openwop.it.tool-catalog-compact-projection.serves-the-tools-compacttooldescriptor-projection-closed-shape-bounded-inputsche', 'tool-catalog.md §compact', 'compact inputSchema MUST be top-level type:"object" with a properties map'),
104
106
  ).toBe(true);
105
107
  // Total (any-depth), schema-aware: a nested oneOf/$ref under a property
106
108
  // schema is exactly the verbosity the compact view exists to drop.
107
109
  const banned = findBannedInputSchemaKeyword(input);
108
110
  expect(
109
111
  banned,
110
- driver.describe('tool-catalog.md §compact', `compact inputSchema MUST NOT use $ref/oneOf/allOf/anyOf/not/patternProperties/dependentSchemas at any nesting depth (found "${banned ?? 'none'}")`),
112
+ req('openwop.it.tool-catalog-compact-projection.serves-the-tools-compacttooldescriptor-projection-closed-shape-bounded-inputsche', 'tool-catalog.md §compact', `compact inputSchema MUST NOT use $ref/oneOf/allOf/anyOf/not/patternProperties/dependentSchemas at any nesting depth (found "${banned ?? 'none'}")`),
111
113
  ).toBe(null);
112
114
  }
113
115
  }
@@ -123,7 +125,7 @@ describe('tool-catalog-compact-projection (RFC 0112 §compact)', () => {
123
125
  standardIds.size === compactIds.size && [...standardIds].every((id) => compactIds.has(id));
124
126
  expect(
125
127
  sameSet,
126
- driver.describe(
128
+ req('openwop.it.tool-catalog-compact-projection.serves-the-tools-compacttooldescriptor-projection-closed-shape-bounded-inputsche',
127
129
  'tool-catalog.md §compact',
128
130
  `compact tools[] MUST carry the same toolId set as the standard view (standard=${[...standardIds].sort().join(',')} compact=${[...compactIds].sort().join(',')})`,
129
131
  ),
@@ -136,12 +138,12 @@ describe('tool-catalog-compact-projection (RFC 0112 §compact)', () => {
136
138
  if (one.status === 200) {
137
139
  expect(
138
140
  validate(one.json),
139
- driver.describe('compact-tool-descriptor.schema.json', `GET /v1/tools/{toolId}?view=compact MUST return a valid CompactToolDescriptor (${ajv.errorsText(validate.errors)})`),
141
+ req('openwop.it.tool-catalog-compact-projection.serves-the-tools-compacttooldescriptor-projection-closed-shape-bounded-inputsche', 'compact-tool-descriptor.schema.json', `GET /v1/tools/{toolId}?view=compact MUST return a valid CompactToolDescriptor (${ajv.errorsText(validate.errors)})`),
140
142
  ).toBe(true);
141
143
  const got = one.json;
142
144
  expect(
143
145
  got && typeof got === 'object' && (got as { toolId?: unknown }).toolId === id,
144
- driver.describe('tool-catalog.md §compact', 'GET /v1/tools/{toolId}?view=compact MUST return the requested descriptor'),
146
+ req('openwop.it.tool-catalog-compact-projection.serves-the-tools-compacttooldescriptor-projection-closed-shape-bounded-inputsche', 'tool-catalog.md §compact', 'GET /v1/tools/{toolId}?view=compact MUST return the requested descriptor'),
145
147
  ).toBe(true);
146
148
  }
147
149
  }
@@ -40,6 +40,8 @@ import {
40
40
  SAFETY_TIERS,
41
41
  TOOL_CONTENT_FORBIDDEN,
42
42
  } from '../lib/toolCatalog.js';
43
+ import { req } from '../lib/requirement-ids.js';
44
+ import { softSkip } from '../lib/soft-skip.js';
43
45
 
44
46
  function loadSchema(name: string): Record<string, unknown> {
45
47
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -49,7 +51,7 @@ function expectContentFree(d: Record<string, unknown>, where: string): void {
49
51
  for (const f of TOOL_CONTENT_FORBIDDEN) {
50
52
  expect(
51
53
  !(f in d),
52
- driver.describe('RFC 0078 §F (SR-1)', `${where} MUST be content-free (no ${f})`),
54
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'RFC 0078 §F (SR-1)', `${where} MUST be content-free (no ${f})`),
53
55
  ).toBe(true);
54
56
  }
55
57
  }
@@ -67,25 +69,25 @@ describe('tool-catalog-projection (RFC 0078 §B/§F)', () => {
67
69
  const unauth = await driver.get('/v1/tools', { authenticated: false });
68
70
  expect(
69
71
  unauth.status === 401,
70
- driver.describe('tool-catalog.md §B', 'GET /v1/tools MUST require authentication (401 unauthenticated)'),
72
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'tool-catalog.md §B', 'GET /v1/tools MUST require authentication (401 unauthenticated)'),
71
73
  ).toBe(true);
72
74
 
73
75
  // ---- Leg 1: the list (§B) -------------------------------------------
74
76
  const tools = await listTools();
75
- if (tools === null) return; // host advertises the cap but doesn't serve the read — soft-skip the rest
77
+ if (tools === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `tools === null` returned early (host advertises the cap but doesn\'t serve the read — soft-skip the rest)'); // host advertises the cap but doesn't serve the read — soft-skip the rest
76
78
 
77
79
  for (const t of tools) {
78
80
  expect(
79
81
  validate(t),
80
- driver.describe('tool-descriptor.schema.json', `each ToolDescriptor MUST validate (${ajv.errorsText(validate.errors)})`),
82
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'tool-descriptor.schema.json', `each ToolDescriptor MUST validate (${ajv.errorsText(validate.errors)})`),
81
83
  ).toBe(true);
82
84
  expect(
83
85
  typeof t.source === 'string' && TOOL_SOURCES.includes(t.source as string),
84
- driver.describe('tool-catalog.md §C', 'ToolDescriptor.source MUST be in the closed vocabulary'),
86
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'tool-catalog.md §C', 'ToolDescriptor.source MUST be in the closed vocabulary'),
85
87
  ).toBe(true);
86
88
  expect(
87
89
  typeof t.safetyTier === 'string' && SAFETY_TIERS.includes(t.safetyTier as string),
88
- driver.describe('tool-catalog.md §C', 'ToolDescriptor.safetyTier MUST be pure|read|write|exec'),
90
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'tool-catalog.md §C', 'ToolDescriptor.safetyTier MUST be pure|read|write|exec'),
89
91
  ).toBe(true);
90
92
  expectContentFree(t, 'ToolDescriptor');
91
93
  }
@@ -97,14 +99,14 @@ describe('tool-catalog-projection (RFC 0078 §B/§F)', () => {
97
99
  if (one.status === 200) {
98
100
  expect(
99
101
  one.descriptor?.toolId === id,
100
- driver.describe('tool-catalog.md §B', 'GET /v1/tools/{toolId} MUST return the requested descriptor'),
102
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'tool-catalog.md §B', 'GET /v1/tools/{toolId} MUST return the requested descriptor'),
101
103
  ).toBe(true);
102
104
  }
103
105
  }
104
106
  const unknown = await getTool('__conformance_nonexistent_tool__');
105
107
  expect(
106
108
  unknown.status === 404,
107
- driver.describe('tool-catalog.md §B', 'GET /v1/tools/{unknown} MUST 404'),
109
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'tool-catalog.md §B', 'GET /v1/tools/{unknown} MUST 404'),
108
110
  ).toBe(true);
109
111
 
110
112
  // ---- Leg 4: §F-2 cross-principal non-disclosure (env-gated) ---------
@@ -113,7 +115,7 @@ describe('tool-catalog-projection (RFC 0078 §B/§F)', () => {
113
115
  const cross = await getTool(crossId);
114
116
  expect(
115
117
  cross.status === 404,
116
- driver.describe('tool-catalog.md §F-2', 'a tool owned by a different principal MUST 404 (non-disclosure)'),
118
+ req('openwop.it.tool-catalog-projection.lists-schema-valid-tooldescriptors-serves-by-id-404s-is-auth-gated-and-never-dis', 'tool-catalog.md §F-2', 'a tool owned by a different principal MUST 404 (non-disclosure)'),
117
119
  ).toBe(true);
118
120
  }
119
121
  });