@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
@@ -47,6 +47,8 @@ import { SCHEMAS_DIR, FIXTURES_DIR } from '../lib/paths.js';
47
47
  import { driver } from '../lib/driver.js';
48
48
  import { behaviorGate } from '../lib/behavior-gate.js';
49
49
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
50
+ import { req } from '../lib/requirement-ids.js';
51
+ import { softSkip } from '../lib/soft-skip.js';
50
52
 
51
53
  const SCHEMA_PATH = join(SCHEMAS_DIR, 'connection-pack-manifest.schema.json');
52
54
  const APIHOSTS_FIXTURE = join(FIXTURES_DIR, 'connection-packs', 'connection-pack-apihosts-valid.json');
@@ -90,7 +92,7 @@ describe('category: connection-pack apiHosts — schema shape (RFC 0120 §A; inv
90
92
  it('positive: an openapi-reach provider declaring apiHosts validates', () => {
91
93
  expect(
92
94
  validate(apiHostsFixture()),
93
- `connection-packs.md §Manifest item 10: a well-formed apiHosts allow-list MUST validate. Errors: ${JSON.stringify(validate.errors)}`,
95
+ req('openwop.it.connection-pack-apihosts.positive-an-openapi-reach-provider-declaring-apihosts-validates', 'RFC 0120', `connection-packs.md §Manifest item 10: a well-formed apiHosts allow-list MUST validate. Errors: ${JSON.stringify(validate.errors)}`),
94
96
  ).toBe(true);
95
97
  });
96
98
 
@@ -100,16 +102,16 @@ describe('category: connection-pack apiHosts — schema shape (RFC 0120 §A; inv
100
102
  const errs = failsWith(m, 'required');
101
103
  expect(
102
104
  errs.some((e) => (e.params as { missingProperty?: string }).missingProperty === 'apiHosts'),
103
- 'connection-packs.md §Manifest item 13: when reach is openapi, apiHosts is REQUIRED (the provider-level allOf)',
105
+ req('openwop.it.connection-pack-apihosts.conditional-must-item-13-a-allof-an-openapi-reach-provider-that-omits-apihosts-i', 'RFC 0120', 'connection-packs.md §Manifest item 13: when reach is openapi, apiHosts is REQUIRED (the provider-level allOf)'),
104
106
  ).toBe(true);
105
107
  });
106
108
 
107
109
  it('omission OK off the conditional: an mcp-reach provider without apiHosts validates', () => {
108
110
  const m = mcpFixture();
109
- expect(m.provider.apiHosts, 'precondition: the github fixture is mcp-reach and declares no apiHosts').toBeUndefined();
111
+ expect(m.provider.apiHosts, req('openwop.it.connection-pack-apihosts.omission-ok-off-the-conditional-an-mcp-reach-provider-without-apihosts-validates', 'RFC 0120', 'precondition: the github fixture is mcp-reach and declares no apiHosts')).toBeUndefined();
110
112
  expect(
111
113
  validate(m),
112
- `connection-packs.md §Manifest item 13: a non-openapi provider MAY omit apiHosts. Errors: ${JSON.stringify(validate.errors)}`,
114
+ req('openwop.it.connection-pack-apihosts.omission-ok-off-the-conditional-an-mcp-reach-provider-without-apihosts-validates', 'RFC 0120', `connection-packs.md §Manifest item 13: a non-openapi provider MAY omit apiHosts. Errors: ${JSON.stringify(validate.errors)}`),
113
115
  ).toBe(true);
114
116
  });
115
117
 
@@ -120,7 +122,7 @@ describe('category: connection-pack apiHosts — schema shape (RFC 0120 §A; inv
120
122
  const errs = failsWith(m, 'pattern');
121
123
  expect(
122
124
  errs.length,
123
- `connection-packs.md §Manifest item 11: "${bad}" MUST be rejected — apiHosts entries are bare, lowercase, alphabetic-TLD registrable hostnames (connection_pack_invalid_api_host)`,
125
+ req('openwop.it.connection-pack-apihosts.entry-shape-item-11-ipv4-literal-wildcard-port-single-label-uppercase-entries-ar', 'RFC 0120', `connection-packs.md §Manifest item 11: "${bad}" MUST be rejected — apiHosts entries are bare, lowercase, alphabetic-TLD registrable hostnames (connection_pack_invalid_api_host)`),
124
126
  ).toBeGreaterThan(0);
125
127
  }
126
128
  });
@@ -128,16 +130,16 @@ describe('category: connection-pack apiHosts — schema shape (RFC 0120 §A; inv
128
130
 
129
131
  describe('category: connection-pack apiHosts — matching rule (RFC 0120 item 10; invariant connection-pack-egress-host-bound)', () => {
130
132
  it('permits the entry host and its subdomains (eTLD+1 floor)', () => {
131
- expect(matchesApiHost('facebook.com', 'facebook.com'), 'item 10: a request host equal to the entry matches').toBe(true);
132
- expect(matchesApiHost('graph.facebook.com', 'facebook.com'), 'item 10: a subdomain of the entry matches (eTLD+1 floor)').toBe(true);
133
- expect(matchesApiHost('api.example.com', 'example.com'), 'item 10: a subdomain matches').toBe(true);
133
+ expect(matchesApiHost('facebook.com', 'facebook.com'), req('openwop.it.connection-pack-apihosts.permits-the-entry-host-and-its-subdomains-etld-1-floor', 'RFC 0120', 'item 10: a request host equal to the entry matches')).toBe(true);
134
+ expect(matchesApiHost('graph.facebook.com', 'facebook.com'), req('openwop.it.connection-pack-apihosts.permits-the-entry-host-and-its-subdomains-etld-1-floor', 'RFC 0120', 'item 10: a subdomain of the entry matches (eTLD+1 floor)')).toBe(true);
135
+ expect(matchesApiHost('api.example.com', 'example.com'), req('openwop.it.connection-pack-apihosts.permits-the-entry-host-and-its-subdomains-etld-1-floor', 'RFC 0120', 'item 10: a subdomain matches')).toBe(true);
134
136
  });
135
137
 
136
138
  it('a pack MAY tighten to an exact host without admitting siblings', () => {
137
- expect(matchesApiHost('googleads.googleapis.com', 'googleads.googleapis.com'), 'item 10: the tighter exact host matches itself').toBe(true);
139
+ expect(matchesApiHost('googleads.googleapis.com', 'googleads.googleapis.com'), req('openwop.it.connection-pack-apihosts.a-pack-may-tighten-to-an-exact-host-without-admitting-siblings', 'RFC 0120', 'item 10: the tighter exact host matches itself')).toBe(true);
138
140
  expect(
139
141
  matchesApiHost('bigquery.googleapis.com', 'googleads.googleapis.com'),
140
- 'item 10: a sibling subdomain MUST NOT match a tighter exact-host entry',
142
+ req('openwop.it.connection-pack-apihosts.a-pack-may-tighten-to-an-exact-host-without-admitting-siblings', 'RFC 0120', 'item 10: a sibling subdomain MUST NOT match a tighter exact-host entry'),
141
143
  ).toBe(false);
142
144
  });
143
145
 
@@ -145,7 +147,7 @@ describe('category: connection-pack apiHosts — matching rule (RFC 0120 item 10
145
147
  for (const evil of ['notexample.com', 'evil.com', 'example.com.evil.com', 'myexample.com']) {
146
148
  expect(
147
149
  matchesApiHost(evil, 'example.com'),
148
- `item 10: "${evil}" MUST NOT match "example.com" (dot-anchored containment, never a bare substring)`,
150
+ req('openwop.it.connection-pack-apihosts.no-substring-suffix-prefix-escape-non-matching-hosts-fail-closed', 'RFC 0120', `item 10: "${evil}" MUST NOT match "example.com" (dot-anchored containment, never a bare substring)`),
149
151
  ).toBe(false);
150
152
  }
151
153
  });
@@ -163,10 +165,10 @@ async function gate(): Promise<boolean> {
163
165
 
164
166
  describe('connection-pack apiHosts — behavioral egress allow-list (RFC 0120 item 10; capability-gated)', () => {
165
167
  it('permits a credential-bearing egress to an apiHosts match; fails closed otherwise (no substring escape)', async () => {
166
- if (!(await gate())) return;
168
+ if (!(await gate())) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!(await gate())` returned early');
167
169
 
168
170
  const install = await driver.post('/v1/host/sample/connection-packs/install', { manifest: apiHostsFixture() });
169
- if (install.status === 404 || install.status === 403) return; // seam unwired — soft-skip
171
+ if (install.status === 404 || install.status === 403) return softSkip('blocked', 'precondition not met — `install.status === 404 || install.status === 403` returned early (seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip
170
172
 
171
173
  const probe = async (requestHost: string): Promise<EgressResult | undefined> => {
172
174
  const res = await driver.post('/v1/host/sample/connection-packs/egress-check', {
@@ -178,18 +180,18 @@ describe('connection-pack apiHosts — behavioral egress allow-list (RFC 0120 it
178
180
  };
179
181
 
180
182
  const allowed = await probe('graph.facebook.com');
181
- if (allowed === undefined) return; // soft-skip
183
+ if (allowed === undefined) return softSkip('blocked', 'precondition not met — `allowed === undefined` returned early (soft-skip) (seam, prior step, or fixture unavailable)'); // soft-skip
182
184
  expect(
183
185
  allowed.allowed,
184
- driver.describe('connection-packs.md §Manifest item 10', 'a credential-bearing egress to a host matching apiHosts MUST be permitted'),
186
+ req('openwop.it.connection-pack-apihosts.permits-a-credential-bearing-egress-to-an-apihosts-match-fails-closed-otherwise', 'connection-packs.md §Manifest item 10', 'a credential-bearing egress to a host matching apiHosts MUST be permitted'),
185
187
  ).toBe(true);
186
188
 
187
189
  for (const evil of ['evil.com', 'notfacebook.com', 'facebook.com.evil.com']) {
188
190
  const denied = await probe(evil);
189
- if (denied === undefined) return; // soft-skip
191
+ if (denied === undefined) return softSkip('blocked', 'precondition not met — `denied === undefined` returned early (soft-skip) (seam, prior step, or fixture unavailable)'); // soft-skip
190
192
  expect(
191
193
  denied.allowed,
192
- driver.describe('connection-packs.md §Manifest item 10', `egress to "${evil}" (no apiHosts match) MUST fail closed — no credential sent`),
194
+ req('openwop.it.connection-pack-apihosts.permits-a-credential-bearing-egress-to-an-apihosts-match-fails-closed-otherwise', 'connection-packs.md §Manifest item 10', `egress to "${evil}" (no apiHosts match) MUST fail closed — no credential sent`),
193
195
  ).toBe(false);
194
196
  }
195
197
  });
@@ -42,6 +42,7 @@ import Ajv2020 from 'ajv/dist/2020.js';
42
42
  import addFormats from 'ajv-formats';
43
43
  import type { ErrorObject } from 'ajv';
44
44
  import { SCHEMAS_DIR, FIXTURES_DIR } from '../lib/paths.js';
45
+ import { req } from '../lib/requirement-ids.js';
45
46
 
46
47
  const SCHEMA_PATH = join(SCHEMAS_DIR, 'connection-pack-manifest.schema.json');
47
48
  const FIXTURE_PATH = join(FIXTURES_DIR, 'connection-packs', 'connection-pack-github.json');
@@ -69,7 +70,7 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
69
70
  it('positive: the connection-pack-github fixture validates cleanly', () => {
70
71
  expect(
71
72
  validate(fixture()),
72
- `connection-packs.md §Manifest clause 1: a well-formed kind:"connection" manifest MUST validate. Errors: ${JSON.stringify(validate.errors)}`,
73
+ req('openwop.it.connection-pack-manifest-valid.positive-the-connection-pack-github-fixture-validates-cleanly', 'connection-packs.md', `connection-packs.md §Manifest clause 1: a well-formed kind:"connection" manifest MUST validate. Errors: ${JSON.stringify(validate.errors)}`),
73
74
  ).toBe(true);
74
75
  });
75
76
 
@@ -78,10 +79,10 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
78
79
  properties?: Record<string, { properties?: Record<string, unknown>; required?: string[] }>;
79
80
  };
80
81
  const connections = caps.properties?.connections;
81
- expect(connections, 'capabilities.md §connections — the connections block MUST be declared').toBeDefined();
82
+ expect(connections, req('openwop.it.connection-pack-manifest-valid.capabilities-schema-json-declares-connections-packssupported-rfc-0095-c', 'RFC 0095 §C', 'capabilities.md §connections — the connections block MUST be declared')).toBeDefined();
82
83
  expect(
83
84
  connections?.properties?.packsSupported,
84
- 'RFC 0095 §C — connections.packsSupported MUST be declared',
85
+ req('openwop.it.connection-pack-manifest-valid.capabilities-schema-json-declares-connections-packssupported-rfc-0095-c', 'RFC 0095 §C', 'RFC 0095 §C — connections.packsSupported MUST be declared'),
85
86
  ).toBeDefined();
86
87
  });
87
88
 
@@ -90,7 +91,7 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
90
91
  const errs = failsWith(m, 'const');
91
92
  expect(
92
93
  errs.length,
93
- 'connection-packs.md §Manifest clause 1: kind MUST be the const "connection"',
94
+ req('openwop.it.connection-pack-manifest-valid.negative-the-kind-discriminator-routes-other-kinds-away-kind-node-rejected', 'connection-packs.md', 'connection-packs.md §Manifest clause 1: kind MUST be the const "connection"'),
94
95
  ).toBeGreaterThan(0);
95
96
  });
96
97
 
@@ -102,7 +103,7 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
102
103
  const errs = failsWith(m, 'additionalProperties');
103
104
  expect(
104
105
  errs.some((e) => (e.params as { additionalProperty?: string }).additionalProperty === 'nodes'),
105
- 'node-packs.md §"Pack kinds": one kind per pack — a foreign `nodes[]` field MUST be rejected (additionalProperties:false)',
106
+ req('openwop.it.connection-pack-manifest-valid.negative-a-manifest-mixing-provider-and-nodes-is-rejected-pack-kind-invalid-at-t', 'connection-packs.md', 'node-packs.md §"Pack kinds": one kind per pack — a foreign `nodes[]` field MUST be rejected (additionalProperties:false)'),
106
107
  ).toBe(true);
107
108
  });
108
109
 
@@ -112,7 +113,7 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
112
113
  const errs = failsWith(m, 'pattern');
113
114
  expect(
114
115
  errs.length,
115
- 'connection-packs.md §Manifest clause 3: auth endpoints MUST be absolute https:// URLs',
116
+ req('openwop.it.connection-pack-manifest-valid.negative-a-non-https-token-endpoint-is-rejected-clause-3', 'connection-packs.md', 'connection-packs.md §Manifest clause 3: auth endpoints MUST be absolute https:// URLs'),
116
117
  ).toBeGreaterThan(0);
117
118
  });
118
119
 
@@ -120,7 +121,7 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
120
121
  const m = { ...fixture(), version: '1.0.0-alpha.1' };
121
122
  expect(
122
123
  validate(m),
123
- `connection-packs.md §Manifest clause 6: prerelease ordering is resolution-time SemVer §11, not manifest shape. Errors: ${JSON.stringify(validate.errors)}`,
124
+ req('openwop.it.connection-pack-manifest-valid.positive-a-semver-prerelease-version-is-schema-valid-precedence-is-a-host-concer', 'connection-packs.md', `connection-packs.md §Manifest clause 6: prerelease ordering is resolution-time SemVer §11, not manifest shape. Errors: ${JSON.stringify(validate.errors)}`),
124
125
  ).toBe(true);
125
126
  });
126
127
 
@@ -130,16 +131,16 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
130
131
  m.provider.vendor = 'Google';
131
132
  expect(
132
133
  validate(m),
133
- `connection-packs.md §Manifest clause 16 (RFC 0123): a string provider.vendor MUST validate. Errors: ${JSON.stringify(validate.errors)}`,
134
+ req('openwop.it.connection-pack-manifest-valid.positive-a-provider-vendor-string-validates-rfc-0123', 'RFC 0123', `connection-packs.md §Manifest clause 16 (RFC 0123): a string provider.vendor MUST validate. Errors: ${JSON.stringify(validate.errors)}`),
134
135
  ).toBe(true);
135
136
  });
136
137
 
137
138
  it('positive: a manifest OMITTING provider.vendor still validates (back-compat, RFC 0123)', () => {
138
139
  const m = fixture();
139
- expect('vendor' in m.provider, 'the base fixture omits vendor').toBe(false);
140
+ expect('vendor' in m.provider, req('openwop.it.connection-pack-manifest-valid.positive-a-manifest-omitting-provider-vendor-still-validates-back-compat-rfc-012', 'RFC 0123', 'the base fixture omits vendor')).toBe(false);
140
141
  expect(
141
142
  validate(m),
142
- `connection-packs.md §Manifest clause 16 (RFC 0123): vendor is OPTIONAL — a manifest without it MUST remain valid. Errors: ${JSON.stringify(validate.errors)}`,
143
+ req('openwop.it.connection-pack-manifest-valid.positive-a-manifest-omitting-provider-vendor-still-validates-back-compat-rfc-012', 'RFC 0123', `connection-packs.md §Manifest clause 16 (RFC 0123): vendor is OPTIONAL — a manifest without it MUST remain valid. Errors: ${JSON.stringify(validate.errors)}`),
143
144
  ).toBe(true);
144
145
  });
145
146
 
@@ -149,7 +150,7 @@ describe('category: connection-pack manifest validation (RFC 0095 §A)', () => {
149
150
  const errs = failsWith(m, 'type');
150
151
  expect(
151
152
  errs.some((e) => e.instancePath === '/provider/vendor'),
152
- 'connection-packs.md §Manifest clause 16 (RFC 0123): provider.vendor MUST be a string — an array MUST be rejected',
153
+ req('openwop.it.connection-pack-manifest-valid.negative-a-non-string-provider-vendor-is-rejected-rfc-0123', 'RFC 0123', 'connection-packs.md §Manifest clause 16 (RFC 0123): provider.vendor MUST be a string — an array MUST be rejected'),
153
154
  ).toBe(true);
154
155
  });
155
156
  });
@@ -40,6 +40,8 @@ import { SCHEMAS_DIR, FIXTURES_DIR } from '../lib/paths.js';
40
40
  import { driver } from '../lib/driver.js';
41
41
  import { behaviorGate } from '../lib/behavior-gate.js';
42
42
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
43
+ import { req } from '../lib/requirement-ids.js';
44
+ import { softSkip } from '../lib/soft-skip.js';
43
45
 
44
46
  const SCHEMA_PATH = join(SCHEMAS_DIR, 'connection-pack-manifest.schema.json');
45
47
  const FIXTURE_PATH = join(FIXTURES_DIR, 'connection-packs', 'connection-pack-github.json');
@@ -80,7 +82,7 @@ describe('connection-pack-no-credential-material: schema layer (always-on, serve
80
82
  for (const [where, m] of [['root', atRoot], ['provider', atProvider], ['provider.auth', atAuth]] as const) {
81
83
  expect(
82
84
  validate(m),
83
- `SECURITY invariant connection-pack-no-credential-material — a property named "${name}" at ${where} MUST NOT validate (additionalProperties:false)`,
85
+ req('openwop.it.connection-pack-no-credential-material.every-blocklisted-property-name-is-schema-rejected-at-the-root-provider-and-auth', 'connection-packs.md', `SECURITY invariant connection-pack-no-credential-material — a property named "${name}" at ${where} MUST NOT validate (additionalProperties:false)`),
84
86
  ).toBe(false);
85
87
  }
86
88
  }
@@ -90,11 +92,11 @@ describe('connection-pack-no-credential-material: schema layer (always-on, serve
90
92
  const m = fixture();
91
93
  expect(
92
94
  typeof (m.provider.auth.endpoints as Record<string, string>).token,
93
- 'fixture sanity — the github fixture declares the token endpoint',
95
+ req('openwop.it.connection-pack-no-credential-material.the-exemption-provider-auth-endpoints-token-the-token-endpoint-url-is-valid', 'connection-packs.md', 'fixture sanity — the github fixture declares the token endpoint'),
94
96
  ).toBe('string');
95
97
  expect(
96
98
  validate(m),
97
- `connection-packs.md §Manifest clause 2 — the property named "token" at exactly provider.auth.endpoints.token is the OAuth token-endpoint URL and MUST validate. Errors: ${JSON.stringify(validate.errors)}`,
99
+ req('openwop.it.connection-pack-no-credential-material.the-exemption-provider-auth-endpoints-token-the-token-endpoint-url-is-valid', 'connection-packs.md', `connection-packs.md §Manifest clause 2 — the property named "token" at exactly provider.auth.endpoints.token is the OAuth token-endpoint URL and MUST validate. Errors: ${JSON.stringify(validate.errors)}`),
98
100
  ).toBe(true);
99
101
  });
100
102
  });
@@ -107,16 +109,16 @@ describe('connection-pack-no-credential-material: specific rejection code (capab
107
109
  const leaky = fixture();
108
110
  (leaky.provider.auth as Record<string, unknown>).clientSecret = 'ghs_conformance_canary';
109
111
  const res = await driver.post('/v1/host/sample/connection-packs/install', { manifest: leaky });
110
- if (res.status === 404 || res.status === 403) return; // seam unwired — soft-skip
112
+ if (res.status === 404 || res.status === 403) return softSkip('blocked', 'precondition not met — `res.status === 404 || res.status === 403` returned early (seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip
111
113
 
112
114
  const body = res.json as { installed?: boolean; errors?: Array<{ code?: string }> } | undefined;
113
115
  expect(
114
116
  body?.installed,
115
- driver.describe('connection-packs.md §Manifest clause 2', 'a manifest carrying credential material MUST NOT install'),
117
+ req('openwop.it.connection-pack-no-credential-material.installing-a-manifest-carrying-clientsecret-is-rejected-with-connection-pack-cre', 'connection-packs.md §Manifest clause 2', 'a manifest carrying credential material MUST NOT install'),
116
118
  ).toBe(false);
117
119
  expect(
118
120
  (body?.errors ?? []).some((e) => e.code === 'connection_pack_credential_material'),
119
- driver.describe(
121
+ req('openwop.it.connection-pack-no-credential-material.installing-a-manifest-carrying-clientsecret-is-rejected-with-connection-pack-cre',
120
122
  'connection-packs.md §Manifest clause 2',
121
123
  'the credential-material scan runs BEFORE generic schema validation — the SPECIFIC code connection_pack_credential_material MUST surface, not a generic shape error',
122
124
  ),
@@ -23,6 +23,7 @@ import Ajv2020 from 'ajv/dist/2020.js';
23
23
  import addFormats from 'ajv-formats';
24
24
  import type { ErrorObject } from 'ajv';
25
25
  import { SCHEMAS_DIR, FIXTURES_DIR } from '../lib/paths.js';
26
+ import { req } from '../lib/requirement-ids.js';
26
27
 
27
28
  const SCHEMA_PATH = join(SCHEMAS_DIR, 'connection-pack-manifest.schema.json');
28
29
  const FIXTURE_PATH = join(FIXTURES_DIR, 'connection-packs', 'connection-pack-github.json');
@@ -60,7 +61,7 @@ describe('connection-pack-reach-exclusive (RFC 0095 §B.5)', () => {
60
61
  for (const reach of [MCP, OPENAPI, INTEGRATION]) {
61
62
  expect(
62
63
  validate(withReach(reach)),
63
- `connection-packs.md §Manifest clause 5: a single reach mode (${Object.keys(reach)[0]}) MUST validate. Errors: ${JSON.stringify(validate.errors)}`,
64
+ req('openwop.it.connection-pack-reach-exclusive.positive-each-reach-mode-validates-alone', 'connection-packs.md', `connection-packs.md §Manifest clause 5: a single reach mode (${Object.keys(reach)[0]}) MUST validate. Errors: ${JSON.stringify(validate.errors)}`),
64
65
  ).toBe(true);
65
66
  }
66
67
  });
@@ -69,7 +70,7 @@ describe('connection-pack-reach-exclusive (RFC 0095 §B.5)', () => {
69
70
  const errs = failsWith(withReach({ ...MCP, ...OPENAPI }), 'maxProperties');
70
71
  expect(
71
72
  errs.length,
72
- 'connection-packs.md §Manifest clause 5: reach MUST specify exactly one of mcp/openapi/integration',
73
+ req('openwop.it.connection-pack-reach-exclusive.negative-two-reach-modes-are-rejected-maxproperties-1', 'connection-packs.md', 'connection-packs.md §Manifest clause 5: reach MUST specify exactly one of mcp/openapi/integration'),
73
74
  ).toBeGreaterThan(0);
74
75
  });
75
76
 
@@ -77,7 +78,7 @@ describe('connection-pack-reach-exclusive (RFC 0095 §B.5)', () => {
77
78
  const errs = failsWith(withReach({}), 'minProperties');
78
79
  expect(
79
80
  errs.length,
80
- 'connection-packs.md §Manifest clause 5: reach MUST declare a mode — an empty object is invalid',
81
+ req('openwop.it.connection-pack-reach-exclusive.negative-an-empty-reach-is-rejected-minproperties-1', 'connection-packs.md', 'connection-packs.md §Manifest clause 5: reach MUST declare a mode — an empty object is invalid'),
81
82
  ).toBeGreaterThan(0);
82
83
  });
83
84
 
@@ -85,7 +86,7 @@ describe('connection-pack-reach-exclusive (RFC 0095 §B.5)', () => {
85
86
  const errs = failsWith(withReach({ grpc: { url: 'https://example.com' } }), 'additionalProperties');
86
87
  expect(
87
88
  errs.some((e) => (e.params as { additionalProperty?: string }).additionalProperty === 'grpc'),
88
- 'connection-packs.md §Manifest clause 5: the reach vocabulary is closed (mcp | openapi | integration)',
89
+ req('openwop.it.connection-pack-reach-exclusive.negative-an-unknown-reach-mode-is-rejected-additionalproperties-false', 'connection-packs.md', 'connection-packs.md §Manifest clause 5: the reach vocabulary is closed (mcp | openapi | integration)'),
89
90
  ).toBe(true);
90
91
  });
91
92
  });
@@ -30,6 +30,8 @@ import { FIXTURES_DIR } from '../lib/paths.js';
30
30
  import { driver } from '../lib/driver.js';
31
31
  import { behaviorGate } from '../lib/behavior-gate.js';
32
32
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
33
+ import { req } from '../lib/requirement-ids.js';
34
+ import { softSkip } from '../lib/soft-skip.js';
33
35
 
34
36
  const FIXTURE_PATH = join(FIXTURES_DIR, 'connection-packs', 'connection-pack-github.json');
35
37
 
@@ -54,13 +56,13 @@ describe('connection-pack-write-reconsent (RFC 0095 §B.4)', () => {
54
56
  provider: 'github',
55
57
  requested: ['read', 'write'],
56
58
  });
57
- if (res.status === 404 || res.status === 403) return; // seam unwired — soft-skip
59
+ if (res.status === 404 || res.status === 403) return softSkip('blocked', 'precondition not met — `res.status === 404 || res.status === 403` returned early (seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip
58
60
 
59
61
  const plan = res.json as ConsentPlan | undefined;
60
62
  const steps = plan?.steps ?? [];
61
63
  expect(
62
64
  steps.length >= 2,
63
- driver.describe(
65
+ req('openwop.it.connection-pack-write-reconsent.write-scope-groups-are-a-separate-consent-step-never-bundled-into-the-initial-re',
64
66
  'connection-packs.md §Manifest clause 4',
65
67
  'requesting read + write scope groups MUST plan write as a SEPARATE consent step (≥ 2 steps)',
66
68
  ),
@@ -70,7 +72,7 @@ describe('connection-pack-write-reconsent (RFC 0095 §B.4)', () => {
70
72
  first.includesWrite === true || (first.groups ?? []).some((g) => g.access === 'write');
71
73
  expect(
72
74
  firstHasWrite,
73
- driver.describe(
75
+ req('openwop.it.connection-pack-write-reconsent.write-scope-groups-are-a-separate-consent-step-never-bundled-into-the-initial-re',
74
76
  'connection-packs.md §Manifest clause 4',
75
77
  'the INITIAL authorization step MUST NOT bundle write scopes',
76
78
  ),
@@ -84,7 +86,7 @@ describe('connection-pack-write-reconsent (RFC 0095 §B.4)', () => {
84
86
  const roSteps = (readOnly.json as ConsentPlan | undefined)?.steps ?? [];
85
87
  expect(
86
88
  roSteps.length,
87
- driver.describe('connection-packs.md §Manifest clause 4', 'a read-only request plans a single consent step'),
89
+ req('openwop.it.connection-pack-write-reconsent.write-scope-groups-are-a-separate-consent-step-never-bundled-into-the-initial-re', 'connection-packs.md §Manifest clause 4', 'a read-only request plans a single consent step'),
88
90
  ).toBe(1);
89
91
  }
90
92
  });
@@ -34,6 +34,8 @@ import { FIXTURES_DIR } from '../lib/paths.js';
34
34
  import { driver } from '../lib/driver.js';
35
35
  import { behaviorGate } from '../lib/behavior-gate.js';
36
36
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
37
+ import { req } from '../lib/requirement-ids.js';
38
+ import { softSkip } from '../lib/soft-skip.js';
37
39
 
38
40
  const FIXTURE_PATH = join(FIXTURES_DIR, 'connection-packs', 'connection-pack-github.json');
39
41
 
@@ -64,25 +66,25 @@ async function gate(): Promise<boolean> {
64
66
 
65
67
  describe('connection-provider-resolution (RFC 0095 §B.6/§B.8)', () => {
66
68
  it('an installed pack resolves its provider id; an unknown provider is unresolved', async () => {
67
- if (!(await gate())) return;
69
+ if (!(await gate())) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!(await gate())` returned early');
68
70
 
69
71
  const install = await driver.post('/v1/host/sample/connection-packs/install', { manifest: fixture() });
70
- if (install.status === 404 || install.status === 403) return; // seam unwired — soft-skip
72
+ if (install.status === 404 || install.status === 403) return softSkip('blocked', 'precondition not met — `install.status === 404 || install.status === 403` returned early (seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip
71
73
  const installed = install.json as InstallResult | undefined;
72
74
  expect(
73
75
  installed?.installed,
74
- driver.describe('connection-packs.md §Manifest clause 1', 'a well-formed connection pack MUST install'),
76
+ req('openwop.it.connection-provider-resolution.an-installed-pack-resolves-its-provider-id-an-unknown-provider-is-unresolved', 'connection-packs.md §Manifest clause 1', 'a well-formed connection pack MUST install'),
75
77
  ).toBe(true);
76
78
 
77
79
  const hit = await driver.post('/v1/host/sample/connection-packs/resolve', { provider: 'github' });
78
80
  const resolved = hit.json as ResolveResult | undefined;
79
81
  expect(
80
82
  resolved?.resolved,
81
- driver.describe('connection-packs.md §Manifest clause 6', 'provider "github" MUST resolve against the installed pack whose provider.id matches'),
83
+ req('openwop.it.connection-provider-resolution.an-installed-pack-resolves-its-provider-id-an-unknown-provider-is-unresolved', 'connection-packs.md §Manifest clause 6', 'provider "github" MUST resolve against the installed pack whose provider.id matches'),
82
84
  ).toBe(true);
83
85
  expect(
84
86
  resolved?.source,
85
- driver.describe('connection-packs.md §Manifest clause 6', 'the installed pack is the resolution source'),
87
+ req('openwop.it.connection-provider-resolution.an-installed-pack-resolves-its-provider-id-an-unknown-provider-is-unresolved', 'connection-packs.md §Manifest clause 6', 'the installed pack is the resolution source'),
86
88
  ).toBe('pack');
87
89
 
88
90
  const miss = await driver.post('/v1/host/sample/connection-packs/resolve', {
@@ -91,35 +93,35 @@ describe('connection-provider-resolution (RFC 0095 §B.6/§B.8)', () => {
91
93
  const unresolved = miss.json as ResolveResult | undefined;
92
94
  expect(
93
95
  unresolved?.resolved,
94
- driver.describe('connection-packs.md §Manifest clause 6', 'a provider with no installed pack and no built-in MUST NOT resolve'),
96
+ req('openwop.it.connection-provider-resolution.an-installed-pack-resolves-its-provider-id-an-unknown-provider-is-unresolved', 'connection-packs.md §Manifest clause 6', 'a provider with no installed pack and no built-in MUST NOT resolve'),
95
97
  ).toBe(false);
96
98
  expect(
97
99
  unresolved?.code,
98
- driver.describe('connection-packs.md §Manifest clause 6', 'the refusal code MUST be connection_provider_unresolved'),
100
+ req('openwop.it.connection-provider-resolution.an-installed-pack-resolves-its-provider-id-an-unknown-provider-is-unresolved', 'connection-packs.md §Manifest clause 6', 'the refusal code MUST be connection_provider_unresolved'),
99
101
  ).toBe('connection_provider_unresolved');
100
102
  });
101
103
 
102
104
  it('an installed prerelease does not outrank a built-in release — conflict surfaces (SemVer §11)', async () => {
103
- if (!(await gate())) return;
105
+ if (!(await gate())) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!(await gate())` returned early');
104
106
 
105
107
  const prerelease = { ...fixture(), version: '1.0.0-alpha.1' };
106
108
  prerelease.provider = { ...prerelease.provider, id: 'conformance-prerelease-probe' };
107
109
  const install = await driver.post('/v1/host/sample/connection-packs/install', { manifest: prerelease });
108
- if (install.status === 404 || install.status === 403) return; // seam unwired — soft-skip
110
+ if (install.status === 404 || install.status === 403) return softSkip('blocked', 'precondition not met — `install.status === 404 || install.status === 403` returned early (seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip
109
111
  expect(
110
112
  (install.json as InstallResult | undefined)?.installed,
111
- driver.describe('connection-packs.md §Manifest clause 1', 'a prerelease-versioned pack is shape-valid and MUST install'),
113
+ req('openwop.it.connection-provider-resolution.an-installed-prerelease-does-not-outrank-a-built-in-release-conflict-surfaces-se', 'connection-packs.md §Manifest clause 1', 'a prerelease-versioned pack is shape-valid and MUST install'),
112
114
  ).toBe(true);
113
115
 
114
116
  const res = await driver.post('/v1/host/sample/connection-packs/resolve', {
115
117
  provider: 'conformance-prerelease-probe',
116
118
  simulateBuiltinVersion: '1.0.0',
117
119
  });
118
- if (res.status === 404 || res.status === 403) return; // simulate knob unwired — soft-skip
120
+ if (res.status === 404 || res.status === 403) return softSkip('blocked', 'precondition not met — `res.status === 404 || res.status === 403` returned early (simulate knob unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // simulate knob unwired — soft-skip
119
121
  const body = res.json as ResolveResult | undefined;
120
122
  expect(
121
123
  body?.code,
122
- driver.describe(
124
+ req('openwop.it.connection-provider-resolution.an-installed-prerelease-does-not-outrank-a-built-in-release-conflict-surfaces-se',
123
125
  'connection-packs.md §Manifest clause 6',
124
126
  'SemVer §11: 1.0.0-alpha.1 < 1.0.0 — the installed pack is NOT greater-or-equal, so the host MUST surface connection_provider_conflict rather than silently choosing',
125
127
  ),
@@ -127,16 +129,16 @@ describe('connection-provider-resolution (RFC 0095 §B.6/§B.8)', () => {
127
129
  });
128
130
 
129
131
  it('rejection isolation: one rejected pack never takes down the install path (§B.8)', async () => {
130
- if (!(await gate())) return;
132
+ if (!(await gate())) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!(await gate())` returned early');
131
133
 
132
134
  const leaky = fixture();
133
135
  leaky.provider = { ...leaky.provider, id: 'conformance-isolation-probe' };
134
136
  (leaky.provider.auth as Record<string, unknown>).clientSecret = 'ghs_conformance_canary';
135
137
  const bad = await driver.post('/v1/host/sample/connection-packs/install', { manifest: leaky });
136
- if (bad.status === 404 || bad.status === 403) return; // seam unwired — soft-skip
138
+ if (bad.status === 404 || bad.status === 403) return softSkip('blocked', 'precondition not met — `bad.status === 404 || bad.status === 403` returned early (seam unwired — soft-skip) (seam, prior step, or fixture unavailable)'); // seam unwired — soft-skip
137
139
  expect(
138
140
  (bad.json as InstallResult | undefined)?.installed,
139
- driver.describe('connection-packs.md §Manifest clause 2', 'the credential-carrying manifest MUST NOT install'),
141
+ req('openwop.it.connection-provider-resolution.rejection-isolation-one-rejected-pack-never-takes-down-the-install-path-b-8', 'connection-packs.md §Manifest clause 2', 'the credential-carrying manifest MUST NOT install'),
140
142
  ).toBe(false);
141
143
 
142
144
  const good = { ...fixture() };
@@ -144,7 +146,7 @@ describe('connection-provider-resolution (RFC 0095 §B.6/§B.8)', () => {
144
146
  const after = await driver.post('/v1/host/sample/connection-packs/install', { manifest: good });
145
147
  expect(
146
148
  (after.json as InstallResult | undefined)?.installed,
147
- driver.describe(
149
+ req('openwop.it.connection-provider-resolution.rejection-isolation-one-rejected-pack-never-takes-down-the-install-path-b-8',
148
150
  'connection-packs.md §Manifest clause 8',
149
151
  'a rejected pack means NOT INSTALLED — nothing more; a subsequent valid install MUST succeed',
150
152
  ),
@@ -27,6 +27,7 @@ import { join } from 'node:path';
27
27
  import Ajv2020 from 'ajv/dist/2020.js';
28
28
  import addFormats from 'ajv-formats';
29
29
  import { SCHEMAS_DIR } from '../lib/paths.js';
30
+ import { req } from '../lib/requirement-ids.js';
30
31
 
31
32
  interface SchemaDefs {
32
33
  $defs: Record<string, unknown>;
@@ -82,7 +83,7 @@ describe('category: connector-manifest validity — schema shape (RFC 0045 §A)'
82
83
  ],
83
84
  triggers: ['vendor.acme.salesforce.onRecordChange'],
84
85
  });
85
- expect(ok, JSON.stringify(validate.errors)).toBe(true);
86
+ expect(ok, req('openwop.it.connector-manifest-validity.positive-a-well-formed-connector-block-oauth2-auth-validates', 'RFC 0045 §A/§B', JSON.stringify(validate.errors))).toBe(true);
86
87
  });
87
88
 
88
89
  it('positive: credential-auth variant validates', () => {
@@ -92,11 +93,11 @@ describe('category: connector-manifest validity — schema shape (RFC 0045 §A)'
92
93
  auth: { type: 'credential', key: 'stripe-secret-key', scope: 'workspace' },
93
94
  actions: [{ typeId: 'vendor.acme.stripe.charge', displayName: 'Charge' }],
94
95
  });
95
- expect(ok, JSON.stringify(validate.errors)).toBe(true);
96
+ expect(ok, req('openwop.it.connector-manifest-validity.positive-credential-auth-variant-validates', 'RFC 0045 §A/§B', JSON.stringify(validate.errors))).toBe(true);
96
97
  });
97
98
 
98
99
  it('negative: connector missing displayName is rejected', () => {
99
- expect(validate({ id: 'salesforce' })).toBe(false);
100
+ expect(validate({ id: 'salesforce' }), req('openwop.it.connector-manifest-validity.negative-connector-missing-displayname-is-rejected', 'RFC 0045 §A/§B', 'negative: connector missing displayName is rejected')).toBe(false);
100
101
  });
101
102
 
102
103
  it('negative: an action missing typeId is rejected', () => {
@@ -105,7 +106,7 @@ describe('category: connector-manifest validity — schema shape (RFC 0045 §A)'
105
106
  displayName: 'Salesforce',
106
107
  actions: [{ displayName: 'Upsert' }],
107
108
  });
108
- expect(ok).toBe(false);
109
+ expect(ok, req('openwop.it.connector-manifest-validity.negative-an-action-missing-typeid-is-rejected', 'RFC 0045 §A/§B', 'negative: an action missing typeId is rejected')).toBe(false);
109
110
  });
110
111
 
111
112
  it('negative: an unknown ConnectorAuth type is rejected', () => {
@@ -114,7 +115,7 @@ describe('category: connector-manifest validity — schema shape (RFC 0045 §A)'
114
115
  displayName: 'Salesforce',
115
116
  auth: { type: 'basic', user: 'x' },
116
117
  });
117
- expect(ok).toBe(false);
118
+ expect(ok, req('openwop.it.connector-manifest-validity.negative-an-unknown-connectorauth-type-is-rejected', 'RFC 0045 §A/§B', 'negative: an unknown ConnectorAuth type is rejected')).toBe(false);
118
119
  });
119
120
  });
120
121
 
@@ -130,13 +131,13 @@ describe('category: connector-manifest validity — action resolution (RFC 0045
130
131
  actions: [{ typeId: 'vendor.acme.salesforce.upsert' }, { typeId: 'vendor.acme.salesforce.query' }],
131
132
  triggers: ['vendor.acme.salesforce.onRecordChange'],
132
133
  });
133
- expect(unresolved, 'every connector.actions[].typeId + triggers[] MUST resolve to a nodes[].typeId').toEqual([]);
134
+ expect(unresolved, req('openwop.it.connector-manifest-validity.all-action-trigger-typeids-resolve-to-nodes-in-the-same-manifest', 'RFC 0045 §A/§B', 'every connector.actions[].typeId + triggers[] MUST resolve to a nodes[].typeId')).toEqual([]);
134
135
  });
135
136
 
136
137
  it('an action typeId not in nodes[] is flagged (connector_action_unresolved)', () => {
137
138
  const unresolved = unresolvedReferences(nodeTypeIds, {
138
139
  actions: [{ typeId: 'vendor.acme.salesforce.does-not-exist' }],
139
140
  });
140
- expect(unresolved).toContain('vendor.acme.salesforce.does-not-exist');
141
+ expect(unresolved, req('openwop.it.connector-manifest-validity.an-action-typeid-not-in-nodes-is-flagged-connector-action-unresolved', 'RFC 0045 §A/§B', 'an action typeId not in nodes[] is flagged (connector_action_unresolved)')).toContain('vendor.acme.salesforce.does-not-exist');
141
142
  });
142
143
  });