@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
package/README.md CHANGED
@@ -16,6 +16,15 @@ The suite is intentionally self-contained — it does NOT depend on the referenc
16
16
 
17
17
  ---
18
18
 
19
+
20
+ ## Suite 2.0.0 (v2 charter Phase 3; RFC 0168) — what changed for hosts
21
+
22
+ - **The contract is a peer package.** `@openwop/openwop-conformance@2.x` no longer vendors `api/` and `schemas/`; it declares `@openwop/spec-artifacts` as an exact-pinned peer dependency (install both), resolves the installed peer through Node's resolver, and refuses to start when the peer's version or `CORPUS-STAMP.json` digest differs from `dist/spec-artifacts.lock.json` (RFC 0168 §D.2). `schemas/CORPUS-STAMP.json` in this package is a copy of the peer's stamp, kept at the path hosts already read for provenance.
23
+ - **`--target-major 1|2`** (RFC 0168 §D.3): one package runs the scenarios for either protocol major; `scenario-majors.json` names each file's majors; the default comes from the host's root `preferredVersion` (RFC 0179), else `max(protocolVersions[])`, else 1.
24
+ - **`req()` is the only assertion form** (RFC 0168 §A.1): every assertion carries a requirement id; `requirements.json` lists every id; `requirement-aliases.json` maps a reworded id to its successor. `scripts/check-req-only.mjs` is the gate.
25
+ - **Corpus-coherence scenarios never run against a host.** They live in `src/coherence/`, run in the spec repo's CI (`scripts/check-spec-coherence.mjs`) and produce `evidence/corpus-ledger.json`; a host bundle never contains them. The `--offline` set is `fixtures-valid` only.
26
+ - **1.x continues on `release/1.x`** (`openwop-conformance/v1.16x.y` tags); pre-release 2.x versions publish under the npm dist-tag `next`.
27
+
19
28
  ## Quickstart
20
29
 
21
30
  Two ways to run: the friendly `openwop-conformance` CLI (recommended for
@@ -103,7 +112,7 @@ Exit code is non-zero on any failed assertion. `--certify` distinguishes: `0`
103
112
 
104
113
  ## What's Covered
105
114
 
106
- The current suite has 473 scenario files under `src/scenarios/`.
115
+ The current suite has 444 scenario files under `src/scenarios/`.
107
116
  - 2026-09-03 (suite `1.157.0 -> 1.158.0`, gap G17): NEW `idempotency-concurrent-claim.test.ts` — drives the new `host-sample-test-seams.md` §25 concurrent duplicate-delivery seam for the RFC 0150 §B / `idempotency.md` §"Concurrent duplicates (Layer 2)" atomic-claim MUST, which is unconditional and had no witness of any kind. Asserts every executor mints the SAME `logicalInvocationId` **before** asserting `delivered === 1` — without the identity check a host passes by minting different ids and never colliding, one effect because nothing raced. Not profile-gated and so not opt-out-able (the obligation is unconditional); an unmounted seam records `blocked`, which is not certifiable. Graduates `layer2-invocation-claim-atomic` reference-impl -> protocol.
108
117
  - 2026-08-19 (suite `1.137.0 → 1.138.0`): NEW `durability-poison-exhaustion.test.ts` — RFC 0158 §C.8, the FIRST row of that RFC's conformance table to land. Asserts what `failure-path.test.ts` cannot: not just that deterministically failing work reaches terminal, but that attempts STOP — counted on the log, re-counted after a scaled quiet window, asserted unchanged. A host still redelivering records more. Seam-gated on the existing event-log seam (`blocked` = unobservable, not unmet) and outside every profile floor.
109
118
  - 2026-08-19 (suite `1.136.15 → 1.137.0`): NEW `replay-fanout-suppression.test.ts` — capability-gated on `webhooks.supported`, **outside every profile floor**; witnesses `replay.md` §"Host-initiated fan-out is an external effect", which was the largest normative MUST NOT on the replay surface with no scenario and no SECURITY invariant. Three legs in ONE `it` against ONE receiver and ONE subscription — a positive control, the MUST NOT, and a `branch` boundary leg — because "no delivery arrived" passes identically when delivery never worked, so absence is asserted only after presence is proven on that exact wiring. A host with an SSRF guard correctly refuses the loopback receiver and records `blocked`: **unobservable, not unmet.**
@@ -448,7 +457,7 @@ Server-required (added in 1.7.0):
448
457
  | ------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
449
458
  | **Redaction** | [`capabilities.md`](../spec/v1/capabilities.md) §"Secrets" + NFR-7 + §"aiProviders" | Vendor-neutral assertions that the server doesn't leak secret material. Three scenario groups: (a) discovery shape contract — `secrets` + `aiProviders` advertisements are well-formed regardless of `secrets.supported`; when `supported === true`, scopes MUST be non-empty + `resolution === 'host-managed'`; `byok ⊆ supported`. (b) bearer-token redaction — invalid Bearer canary in `Authorization` header is not echoed in the 401 response body. (c) credentialRef echo control — gated on `secrets.supported === true`; canary planted in `configurable.ai.credentialRef` MUST NOT appear in any RunEvent payload (poll-based capture; transport-agnostic). Uses runtime-built canary fixtures (`lib/canaries.ts`) that defeat static secret scanners. 6 scenarios. |
450
459
 
451
- Current source tree: 473 scenario files. Use [`coverage.md`](./coverage.md) for current grade/gap tracking.
460
+ Current source tree: 444 scenario files. Use [`coverage.md`](./coverage.md) for current grade/gap tracking.
452
461
 
453
462
  ## Remaining Gaps
454
463
 
package/dist/cli.js CHANGED
@@ -57,6 +57,7 @@ function parseArgs(argv) {
57
57
  // `--bundle-version 1` through the RFC 0148 migration window (ends
58
58
  // 2026-11-10) and is removed at v2.0 (spec/v1/deprecations.json).
59
59
  let bundleVersion = '2';
60
+ let targetMajor;
60
61
  let maxWorkers = parseMaxWorkers(process.env.OPENWOP_MAX_WORKERS, 'OPENWOP_MAX_WORKERS');
61
62
  for (let i = 0; i < argv.length; i++) {
62
63
  const arg = argv[i] ?? '';
@@ -88,6 +89,15 @@ function parseArgs(argv) {
88
89
  case '--api-key':
89
90
  apiKey = nextValue();
90
91
  break;
92
+ case '--target-major': {
93
+ const v = argv[++i];
94
+ if (v !== '1' && v !== '2') {
95
+ process.stderr.write(`openwop-conformance: --target-major must be 1 or 2 (got ${String(v)})\n`);
96
+ process.exit(2);
97
+ }
98
+ targetMajor = v === '2' ? 2 : 1;
99
+ break;
100
+ }
91
101
  case '--filter':
92
102
  filter = nextValue();
93
103
  break;
@@ -133,6 +143,7 @@ function parseArgs(argv) {
133
143
  implVersion,
134
144
  certify,
135
145
  bundleVersion,
146
+ targetMajor,
136
147
  maxWorkers,
137
148
  };
138
149
  }
@@ -169,6 +180,9 @@ Implementation labels (cosmetic — surface in failure messages):
169
180
  --impl-version <version> Implementation version (env: OPENWOP_IMPLEMENTATION_VERSION)
170
181
 
171
182
  Certification (RFC 0089):
183
+ --target-major <1|2> Suite 2.0.0 (RFC 0168 §D.3): run the scenarios for this protocol
184
+ major. Default: the host's preferredVersion (RFC 0179), else
185
+ max(protocolVersions[]), else 1. Selection is scenario-majors.json.
172
186
  --bundle-version <1|2> Certification bundle format. Default 2 (corrected 2026-09-03, RFC 0168 §E.4; the text said 1 while the code set 2). Version 2 (RFC 0148
173
187
  §C) records per-requirement DISPOSITIONS instead of pass/fail/skip
174
188
  file lists, so "we could not check" stops being indistinguishable
@@ -272,6 +286,34 @@ function scenarioStatesFromReport(report) {
272
286
  return states;
273
287
  }
274
288
  /** Generate + validate + write an RFC 0089 conformance certification bundle. */
289
+ /**
290
+ * Suite 2.0.0 — resolve the target major (RFC 0168 §D.3 / RFC 0179): the flag,
291
+ * else the host's root `preferredVersion`, else max(protocolVersions[]), else 1.
292
+ * Returns the major and the scenario files that target it (scenario-majors.json).
293
+ */
294
+ async function resolveTargetMajor(args, baseUrl, apiKey, conformanceRoot) {
295
+ let major = args.targetMajor;
296
+ let source = 'flag';
297
+ if (major === undefined && baseUrl) {
298
+ try {
299
+ const res = await fetch(`${baseUrl.replace(/\/$/, '')}/.well-known/openwop`, { headers: apiKey ? { authorization: `Bearer ${apiKey}` } : {} });
300
+ const doc = (await res.json());
301
+ const pv = doc.preferredVersion ?? (doc.protocolVersions ?? []).map((v) => v).sort((a, b) => Number(b.split('.')[0]) - Number(a.split('.')[0]))[0];
302
+ if (pv) {
303
+ major = Number(pv.split('.')[0]) >= 2 ? 2 : 1;
304
+ source = doc.preferredVersion ? 'preferredVersion' : 'max(protocolVersions[])';
305
+ }
306
+ }
307
+ catch { /* unreachable host: the default below; the run itself will report the failure */ }
308
+ }
309
+ if (major === undefined) {
310
+ major = 1;
311
+ source = 'default';
312
+ }
313
+ const manifest = JSON.parse(readFileSync(resolvePath(conformanceRoot, 'scenario-majors.json'), 'utf8'));
314
+ const files = Object.entries(manifest.majors).filter(([, m]) => m.includes(major)).map(([f]) => `src/scenarios/${f}`);
315
+ return { major, files, source };
316
+ }
275
317
  async function runCertify(args, baseUrl, apiKey) {
276
318
  const outPath = args.certify;
277
319
  if (outPath === undefined)
@@ -312,6 +354,9 @@ async function runCertify(args, baseUrl, apiKey) {
312
354
  env.OPENWOP_IMPLEMENTATION_NAME = args.impl;
313
355
  if (args.implVersion)
314
356
  env.OPENWOP_IMPLEMENTATION_VERSION = args.implVersion;
357
+ const target = await resolveTargetMajor(args, baseUrl, apiKey, conformanceRoot);
358
+ env.OPENWOP_TARGET_MAJOR = String(target.major);
359
+ process.stderr.write(`openwop-conformance --certify: target major ${target.major} (${target.source}); ${target.files.length} scenario file(s)\n`);
315
360
  const vitestArgs = [
316
361
  'vitest',
317
362
  'run',
@@ -320,6 +365,8 @@ async function runCertify(args, baseUrl, apiKey) {
320
365
  '--reporter=json',
321
366
  `--outputFile=${reportFile}`,
322
367
  ...maxWorkersArgs(args.maxWorkers),
368
+ ...(args.filter ? ['--testNamePattern', args.filter] : []),
369
+ ...target.files,
323
370
  ];
324
371
  const runResult = spawnSync('npx', vitestArgs, { cwd: conformanceRoot, env, stdio: 'inherit' });
325
372
  if (runResult.error) {
@@ -420,7 +467,7 @@ async function runCertify(args, baseUrl, apiKey) {
420
467
  // the discovery it saw. Two runs against differently-configured hosts are
421
468
  // different evidence, and this is what says so.
422
469
  const configSha = createHash('sha256')
423
- .update(`${args.baseUrl}\n${sha256}\n${process.env['OPENWOP_REQUIRE_BEHAVIOR'] ?? ''}`, 'utf8')
470
+ .update(`${baseUrl}\n${sha256}\n${process.env['OPENWOP_REQUIRE_BEHAVIOR'] ?? ''}`, 'utf8')
424
471
  .digest('hex');
425
472
  // Rows come from the ledger (S6). A file that recorded nothing is
426
473
  // `blocked` — unclassified — and, if it sits on a claimed floor, rejected above.
@@ -571,6 +618,12 @@ async function main() {
571
618
  // ancestor config (e.g., a parent monorepo's vite.config.ts) when
572
619
  // the conformance package is used as a workspace member.
573
620
  const vitestArgs = ['run', '--config', resolvePath(conformanceRoot, 'vitest.config.ts')];
621
+ const target = await resolveTargetMajor(args, env.OPENWOP_BASE_URL, env.OPENWOP_API_KEY, conformanceRoot);
622
+ env.OPENWOP_TARGET_MAJOR = String(target.major);
623
+ if (!args.offline) {
624
+ process.stderr.write(`openwop-conformance: target major ${target.major} (${target.source}); ${target.files.length} scenario file(s)\n`);
625
+ vitestArgs.push(...target.files);
626
+ }
574
627
  if (args.offline) {
575
628
  // Suite 1.154.0: the offline set is a DECLARED property of the package —
576
629
  // exactly the server-free scenarios that ship in the tarball and run in
package/dist/lib/paths.js CHANGED
@@ -35,6 +35,7 @@
35
35
  */
36
36
  import { existsSync } from 'node:fs';
37
37
  import { fileURLToPath } from 'node:url';
38
+ import { createRequire } from 'node:module';
38
39
  import { dirname, join, resolve as pathResolve } from 'node:path';
39
40
  // `dirname(fileURLToPath(import.meta.url))` for an ESM module compiled or
40
41
  // run from `src/lib/paths.ts` returns `<pkg>/src/lib/`. The conformance
@@ -43,7 +44,22 @@ import { dirname, join, resolve as pathResolve } from 'node:path';
43
44
  // identical between the two; only the parent of `<pkg>` differs.
44
45
  const HERE = dirname(fileURLToPath(import.meta.url));
45
46
  const PKG_ROOT = pathResolve(HERE, '..', '..');
46
- function resolveFromRoot(root, layout) {
47
+ /**
48
+ * Suite 2.0.0 (RFC 0168 §D.2): in the published layout the CONTRACT (api/ and
49
+ * schemas/) is the `@openwop/spec-artifacts` peer package, not files vendored
50
+ * into this tarball. Resolve its root through Node's resolver from this package
51
+ * so the host's installed peer is what the suite validates against.
52
+ */
53
+ function resolvePeerRoot() {
54
+ try {
55
+ const req = createRequire(join(PKG_ROOT, 'package.json'));
56
+ return dirname(req.resolve('@openwop/spec-artifacts/package.json'));
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ function resolveFromRoot(root, layout, contractRoot = root) {
47
63
  // Two on-disk shapes for the layout root:
48
64
  // - Repo: <root>/schemas, <root>/api, <root>/conformance/fixtures,
49
65
  // <root>/conformance/{fixtures.md,coverage.md}, <root>/spec/v1/*.md
@@ -52,8 +68,8 @@ function resolveFromRoot(root, layout) {
52
68
  // <root>/fixtures.md (when bundled), no spec/v1.
53
69
  // Probe by checking whether `schemas/` lives at the conformance pkg root
54
70
  // (vendored) vs one level up (repo).
55
- const schemasDir = join(root, 'schemas');
56
- const apiDir = join(root, 'api');
71
+ const schemasDir = join(contractRoot, 'schemas');
72
+ const apiDir = join(contractRoot, 'api');
57
73
  const repoFixturesDir = join(root, 'conformance', 'fixtures');
58
74
  const vendoredFixturesDir = join(root, 'fixtures');
59
75
  const fixturesDir = existsSync(repoFixturesDir) ? repoFixturesDir : vendoredFixturesDir;
@@ -131,7 +147,13 @@ function resolveLayout() {
131
147
  if (parentHasSchemas) {
132
148
  return resolveFromRoot(parent, 'repo');
133
149
  }
150
+ const peer = resolvePeerRoot();
151
+ if (peer) {
152
+ return resolveFromRoot(PKG_ROOT, 'published', peer);
153
+ }
134
154
  if (pkgHasSchemas) {
155
+ // A pre-2.0 tarball layout (schemas vendored in-package); kept so an old
156
+ // layout still resolves, but the 2.x stamp check refuses to run without the peer.
135
157
  return resolveFromRoot(PKG_ROOT, 'published');
136
158
  }
137
159
  // Neither — return the published-style resolution rooted at PKG_ROOT
@@ -24,6 +24,20 @@
24
24
  * `~3`, … (vitest allows duplicate titles; the ledger does not allow duplicate
25
25
  * ids). A scenario MAY override the derived id for the current test with
26
26
  * `req()` when it wants a hand-authored, registry-listed id.
27
+ *
28
+ * requireExplicitIds (suite 2.0.0, RFC 0168 §A.1): from 2.0.0 `req(id, section,
29
+ * requirement)` is the ONLY assertion-message form in `src/scenarios` and
30
+ * `src/coherence` — `driver.describe(section, requirement)` is gone from every
31
+ * scenario, and `scripts/check-req-only.mjs` (root) fails the gate when a
32
+ * scenario reintroduces it, when an `expect` carries a bare string message,
33
+ * when an `it` body returns without `softSkip` / `seamAbsent`, or when two
34
+ * `it`s in one file share an explicit id. Every `it` therefore names the
35
+ * requirement it witnesses on the wire; the title-derived allocator below is
36
+ * the fallback for an `it` that makes no cited assertion at all. The ids the
37
+ * 2.0.0 sweep wrote are exactly the ids the allocator derived in 1.x (same
38
+ * stem + slug + `~n` order), so no bundle id changed at the cut-over; an `it`
39
+ * with an interpolated title carries a hand-minted id from the static parts of
40
+ * its title, unique within the file.
27
41
  */
28
42
  export const IT_ID_PREFIX = 'openwop.it.';
29
43
  export const IT_ID_GRAMMAR = /^openwop\.it\.[a-z0-9]+(?:-[a-z0-9]+)*\.[a-z0-9]+(?:-[a-z0-9]+)*(?:~[2-9][0-9]*)?$/;
@@ -64,7 +78,12 @@ export class ItIdAllocator {
64
78
  seen = new Map();
65
79
  allocate(scenarioFile, title) {
66
80
  const base = itRequirementId(scenarioFile, title);
67
- const n = (this.seen.get(base) ?? 0) + 1;
81
+ let n = (this.seen.get(base) ?? 0) + 1;
82
+ // An id a sibling `it` already claimed through `req()` never reached this
83
+ // allocator, so a same-titled `it` that cites nothing must skip past it —
84
+ // otherwise the first explicit `exists` and the derived `exists` collide.
85
+ while (claimedExplicit.has(n === 1 ? base : `${base}~${n}`))
86
+ n++;
68
87
  this.seen.set(base, n);
69
88
  return n === 1 ? base : `${base}~${n}`;
70
89
  }
@@ -76,21 +95,32 @@ export class ItIdAllocator {
76
95
  // Explicit override for the current test.
77
96
  // ---------------------------------------------------------------------------
78
97
  let explicitId = null;
98
+ /** Every id handed to `req()` in this worker — consulted by `ItIdAllocator`. */
99
+ const claimedExplicit = new Set();
79
100
  /**
80
101
  * Attach a hand-authored requirement id to the CURRENT test. The per-`it`
81
102
  * ledger row for this test is recorded under `id` instead of the derived
82
- * title id. Returns the usual `driver.describe`-style message so the call
83
- * doubles as the assertion message:
103
+ * title id. Returns the SAME message shape `driver.describe` returns
104
+ * `[<impl>@<version>] <section>: <requirement>` so a failure still names
105
+ * the implementation under test:
84
106
  *
85
107
  * expect(x, req('openwop.auth.subject-link.leaver-deny', 'auth-profiles.md §Subject linking', 'deactivation MUST deny')).toBe(true)
86
108
  *
109
+ * The implementation label is read straight from `OPENWOP_IMPLEMENTATION_NAME`
110
+ * / `OPENWOP_IMPLEMENTATION_VERSION` with the defaults `env.ts` uses (`unknown`)
111
+ * rather than through `loadEnv()`, so a suite self-test can call `req()`
112
+ * without `OPENWOP_BASE_URL` set.
113
+ *
87
114
  * The id MUST be listed in `conformance/requirements.json` (the generator
88
115
  * collects `req(` first-argument literals); an unlisted id fails the registry
89
116
  * check, so a hand id cannot drift from the registry silently.
90
117
  */
91
118
  export function req(id, specSection, requirement) {
92
119
  explicitId = id;
93
- return `${specSection}: ${requirement}`;
120
+ claimedExplicit.add(id);
121
+ const impl = process.env['OPENWOP_IMPLEMENTATION_NAME']?.trim() ?? 'unknown';
122
+ const version = process.env['OPENWOP_IMPLEMENTATION_VERSION']?.trim() ?? 'unknown';
123
+ return `[${impl}@${version}] ${specSection}: ${requirement}`;
94
124
  }
95
125
  /** setup.ts reads and clears the override after each test. */
96
126
  export function takeExplicitRequirementId() {
@@ -110,6 +110,7 @@ export function resolveFileRecord(states, gateReason, assertionCount, noted, spe
110
110
  // CERTIFIABLE, so these rows stop counting against a host that cannot affect
111
111
  // them. See lib/spec-coherence.ts for why not a new disposition value.
112
112
  if (specCoherenceFile !== undefined
113
+ && process.env.OPENWOP_CORPUS_GATE !== '1' // suite 2.0.0: under the corpus gate the coherence scenario IS the subject
113
114
  && SPEC_COHERENCE_SCENARIOS.has(specCoherenceFile)
114
115
  && !states.includes('fail')
115
116
  && assertionCount === 0) {
@@ -79,38 +79,19 @@
79
79
  * disjoint and jointly exhaustive over the `V1_DIR`-gated files, and a comment
80
80
  * is no longer the only place the exclusion reason lives.
81
81
  */
82
- /** Scenarios whose subject is the corpus. Kept honest by `spec-coherence-registry.test.ts`. */
83
- export const SPEC_COHERENCE_SCENARIOS = new Set([
84
- 'artifact-schema-compile-bounded.test.ts',
85
- 'artifact-type-legacy-ids.test.ts',
86
- 'capability-example-root-layout.test.ts',
87
- 'certification-floor-enforcement.test.ts',
88
- 'chain-subchain-unsupported-refused.test.ts',
89
- 'compensation-profile.test.ts',
90
- 'core-manifest-and-extension-registry.test.ts',
91
- 'discovery-canonical-family-no-shadow.test.ts',
92
- 'edge-condition-truthy-falsy.test.ts',
93
- 'effect-identity-composition.test.ts',
94
- 'effect-identity-cross-scope.test.ts',
95
- 'error-envelope-canonical-shape.test.ts',
96
- 'event-codemap-complete.test.ts',
97
- 'form-content-packs.test.ts',
98
- 'multi-region-effect-vocabulary.test.ts',
99
- 'normative-example-extraction.test.ts',
100
- 'openapi-asyncapi-sdk-parity.test.ts',
101
- 'pack-manifest-extensions.test.ts',
102
- 'protocol-version-grammar.test.ts',
103
- 'registry-declarative-kinds.test.ts',
104
- 'rfc-0147-self-audit.test.ts',
105
- 'rfc-lifecycle-coherence.test.ts',
106
- 'semantic-digest-v2.test.ts',
107
- 'spec-corpus-validity.test.ts',
108
- 'spec-section-citations.test.ts',
109
- 'tool-result-trust-monotone.test.ts',
110
- 'versioned-composition-profiles.test.ts',
111
- 'workflow-chain-internal-flag.test.ts',
112
- 'workload-identity-profile.test.ts',
113
- ]);
82
+ /**
83
+ * Scenarios whose subject is the corpus. Suite 2.0.0 (RFC 0168 §D.1): they
84
+ * live in `src/coherence/`, not `src/scenarios/`, and the set is the DIRECTORY
85
+ * LISTING — one source of truth instead of four (this list, the package.json
86
+ * negations, spec-coherence-scenarios.json and the registry self-test used to
87
+ * each carry a copy). They run in the spec repo's CI (scripts/check-spec-coherence.mjs)
88
+ * and never enter a host bundle; the published tarball excludes the directory.
89
+ */
90
+ import { existsSync, readdirSync } from 'node:fs';
91
+ import { fileURLToPath } from 'node:url';
92
+ import { dirname, join } from 'node:path';
93
+ const COHERENCE_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'coherence');
94
+ export const SPEC_COHERENCE_SCENARIOS = new Set(existsSync(COHERENCE_DIR) ? readdirSync(COHERENCE_DIR).filter((f) => f.endsWith('.test.ts')).sort() : []);
114
95
  /**
115
96
  * Scenarios that gate on `V1_DIR` **and** drive the host, so their `blocked` is
116
97
  * honest: advertised behaviour a missing dependency prevented exercising.
@@ -0,0 +1,5 @@
1
+ {
2
+ "package": "@openwop/spec-artifacts",
3
+ "version": "2.0.0-rc.0",
4
+ "stampSha256": "9596838d163c3c9bc51311776e20216fa6abcd9d315077af05f5301bab4fdcd9"
5
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openwop/openwop-conformance",
3
- "version": "1.162.0",
3
+ "version": "2.0.0-rc.0",
4
4
  "description": "Production-ready black-box conformance suite for OpenWOP v1.0 compliant servers.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,7 +20,7 @@
20
20
  "coverage.md",
21
21
  "requirements.json",
22
22
  "requirement-aliases.json",
23
- "api",
23
+ "scenario-majors.json",
24
24
  "schemas",
25
25
  "vectors",
26
26
  "vitest.config.ts",
@@ -28,35 +28,7 @@
28
28
  "CHANGELOG.md",
29
29
  "LICENSE",
30
30
  "!src/lib/*.test.ts",
31
- "!src/scenarios/artifact-schema-compile-bounded.test.ts",
32
- "!src/scenarios/artifact-type-legacy-ids.test.ts",
33
- "!src/scenarios/capability-example-root-layout.test.ts",
34
- "!src/scenarios/certification-floor-enforcement.test.ts",
35
- "!src/scenarios/chain-subchain-unsupported-refused.test.ts",
36
- "!src/scenarios/compensation-profile.test.ts",
37
- "!src/scenarios/core-manifest-and-extension-registry.test.ts",
38
- "!src/scenarios/discovery-canonical-family-no-shadow.test.ts",
39
- "!src/scenarios/edge-condition-truthy-falsy.test.ts",
40
- "!src/scenarios/effect-identity-composition.test.ts",
41
- "!src/scenarios/effect-identity-cross-scope.test.ts",
42
- "!src/scenarios/error-envelope-canonical-shape.test.ts",
43
- "!src/scenarios/event-codemap-complete.test.ts",
44
- "!src/scenarios/form-content-packs.test.ts",
45
- "!src/scenarios/multi-region-effect-vocabulary.test.ts",
46
- "!src/scenarios/normative-example-extraction.test.ts",
47
- "!src/scenarios/openapi-asyncapi-sdk-parity.test.ts",
48
- "!src/scenarios/pack-manifest-extensions.test.ts",
49
- "!src/scenarios/protocol-version-grammar.test.ts",
50
- "!src/scenarios/registry-declarative-kinds.test.ts",
51
- "!src/scenarios/rfc-0147-self-audit.test.ts",
52
- "!src/scenarios/rfc-lifecycle-coherence.test.ts",
53
- "!src/scenarios/semantic-digest-v2.test.ts",
54
- "!src/scenarios/spec-corpus-validity.test.ts",
55
- "!src/scenarios/spec-section-citations.test.ts",
56
- "!src/scenarios/tool-result-trust-monotone.test.ts",
57
- "!src/scenarios/versioned-composition-profiles.test.ts",
58
- "!src/scenarios/workflow-chain-internal-flag.test.ts",
59
- "!src/scenarios/workload-identity-profile.test.ts"
31
+ "!src/coherence"
60
32
  ],
61
33
  "scripts": {
62
34
  "test": "vitest run",
@@ -66,7 +38,9 @@
66
38
  "build:cli": "tsc -p tsconfig.build.json && chmod +x dist/cli.js",
67
39
  "cli": "tsx src/cli.ts",
68
40
  "prepack": "bash scripts/pack-vendor.sh",
69
- "postpack": "rm -rf api schemas"
41
+ "postpack": "rm -rf schemas",
42
+ "test:coherence": "vitest run --config vitest.coherence.config.ts",
43
+ "test:self": "vitest run --config vitest.selftest.config.ts"
70
44
  },
71
45
  "engines": {
72
46
  "node": ">=20"
@@ -78,6 +52,10 @@
78
52
  },
79
53
  "devDependencies": {
80
54
  "typescript": "^5.6.0",
81
- "@types/node": "^22.0.0"
55
+ "@types/node": "^22.0.0",
56
+ "@openwop/spec-artifacts": "file:../spec-artifacts"
57
+ },
58
+ "peerDependencies": {
59
+ "@openwop/spec-artifacts": "2.0.0-rc.0"
82
60
  }
83
61
  }