@openwop/openwop-conformance 1.163.0 → 2.0.0-rc.1

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 (611) hide show
  1. package/README.md +11 -2
  2. package/dist/cli.js +262 -14
  3. package/dist/lib/certification-bundle-v3.js +142 -0
  4. package/dist/lib/paths.js +25 -3
  5. package/dist/lib/requirement-ids.js +57 -4
  6. package/dist/lib/requirement-ledger.js +1 -0
  7. package/dist/lib/scenario-disposition.js +6 -1
  8. package/dist/lib/spec-coherence.js +13 -32
  9. package/dist/spec-artifacts.lock.json +5 -0
  10. package/package.json +11 -33
  11. package/requirements.json +22892 -11701
  12. package/scenario-majors.json +1493 -0
  13. package/schemas/CORPUS-STAMP.json +137 -5
  14. package/src/cli.ts +236 -19
  15. package/src/global-setup.ts +3 -2
  16. package/src/lib/certification-bundle-v3.ts +175 -0
  17. package/src/lib/corpus-stamp.ts +29 -1
  18. package/src/lib/driver.ts +9 -1
  19. package/src/lib/era2-seed.ts +197 -0
  20. package/src/lib/paths.ts +25 -3
  21. package/src/lib/requirement-ids.ts +54 -4
  22. package/src/lib/requirement-ledger.ts +7 -1
  23. package/src/lib/scenario-disposition.ts +6 -1
  24. package/src/lib/seams.ts +45 -0
  25. package/src/lib/spec-coherence.ts +15 -32
  26. package/src/lib/v2.ts +62 -0
  27. package/src/scenarios/a2a-1-0-agent-card.test.ts +17 -16
  28. package/src/scenarios/a2a-1-0-task-roundtrip.test.ts +11 -10
  29. package/src/scenarios/a2a-card-runtime-consistency.test.ts +18 -17
  30. package/src/scenarios/a2a-peer-authority.test.ts +7 -6
  31. package/src/scenarios/a2a-task-roundtrip.test.ts +30 -29
  32. package/src/scenarios/a2a-version-negotiation.test.ts +16 -14
  33. package/src/scenarios/a2ui-surface-degrades.test.ts +5 -3
  34. package/src/scenarios/a2ui-surface-delta-transport.test.ts +35 -33
  35. package/src/scenarios/a2ui-surface-replay.test.ts +6 -4
  36. package/src/scenarios/a2ui-surface-shape.test.ts +11 -10
  37. package/src/scenarios/a2ui-surface-version-refusal.test.ts +6 -4
  38. package/src/scenarios/a2ui-untrusted-blocks-approval.test.ts +5 -3
  39. package/src/scenarios/agent-capability-degraded-projection.test.ts +12 -11
  40. package/src/scenarios/agent-channel-dispatch.test.ts +18 -16
  41. package/src/scenarios/agent-deployment-lifecycle.test.ts +20 -19
  42. package/src/scenarios/agent-deployment-shape.test.ts +22 -24
  43. package/src/scenarios/agent-eval-run.test.ts +19 -18
  44. package/src/scenarios/agent-eval-suite-shape.test.ts +20 -22
  45. package/src/scenarios/agent-live-allowlist-enforced.test.ts +6 -5
  46. package/src/scenarios/agent-live-invocation-bracket.test.ts +13 -12
  47. package/src/scenarios/agent-live-runtime-shape.test.ts +10 -12
  48. package/src/scenarios/agent-live-structured-output.test.ts +7 -6
  49. package/src/scenarios/agent-loop-iteration-monotonic.test.ts +3 -3
  50. package/src/scenarios/agent-loop-stateful-resume.test.ts +2 -2
  51. package/src/scenarios/agent-loop-version5-shape.test.ts +4 -4
  52. package/src/scenarios/agent-loop-workspace-snapshot.test.ts +3 -3
  53. package/src/scenarios/agent-manifest-role-profile.test.ts +9 -9
  54. package/src/scenarios/agent-manifest-runtime.test.ts +13 -12
  55. package/src/scenarios/agent-org-chart-scoping.test.ts +14 -13
  56. package/src/scenarios/agent-org-chart-shape.test.ts +11 -13
  57. package/src/scenarios/agent-platform-aggregate-evidence.test.ts +5 -4
  58. package/src/scenarios/agent-platform-profile.test.ts +18 -19
  59. package/src/scenarios/agent-requires-capabilities-shape.test.ts +4 -4
  60. package/src/scenarios/agent-roster-attribution.test.ts +18 -17
  61. package/src/scenarios/agent-roster-shape.test.ts +17 -19
  62. package/src/scenarios/agent-verifier-shape.test.ts +11 -11
  63. package/src/scenarios/agentConfidenceEscalation.test.ts +2 -1
  64. package/src/scenarios/agentMemoryCrossTenantIsolation.test.ts +6 -5
  65. package/src/scenarios/agentMemoryRedactionContract.test.ts +2 -1
  66. package/src/scenarios/agentMemoryRoundTrip.test.ts +2 -1
  67. package/src/scenarios/agentMemoryTtlExpiry.test.ts +4 -3
  68. package/src/scenarios/agentMessageReducer.test.ts +2 -1
  69. package/src/scenarios/agentMetadata.test.ts +2 -1
  70. package/src/scenarios/agentPackCatalog.test.ts +23 -21
  71. package/src/scenarios/agentPackExport.test.ts +4 -2
  72. package/src/scenarios/agentPackHandoffSchemaValidation.test.ts +5 -4
  73. package/src/scenarios/agentPackInstall.test.ts +4 -2
  74. package/src/scenarios/agentPackProvenance.test.ts +2 -1
  75. package/src/scenarios/agentReasoningEvents.test.ts +3 -2
  76. package/src/scenarios/agentReasoningStreaming.test.ts +11 -10
  77. package/src/scenarios/agents-run-tool-allowlist.test.ts +14 -12
  78. package/src/scenarios/ai-envelope-shape.test.ts +31 -29
  79. package/src/scenarios/aiEnvelope.capBreached.test.ts +26 -24
  80. package/src/scenarios/aiEnvelope.contractRefusal.test.ts +36 -34
  81. package/src/scenarios/aiEnvelope.correlationReplay.test.ts +17 -15
  82. package/src/scenarios/aiEnvelope.redaction.test.ts +22 -20
  83. package/src/scenarios/aiEnvelope.schemaDrift.test.ts +18 -16
  84. package/src/scenarios/aiEnvelope.trustBoundaryPropagation.test.ts +38 -36
  85. package/src/scenarios/aiEnvelope.universalKinds.test.ts +31 -29
  86. package/src/scenarios/aiproviders-input-shape.test.ts +5 -5
  87. package/src/scenarios/aiproviders-realtimevoice-shape.test.ts +14 -16
  88. package/src/scenarios/aiproviders-selfhosted-honesty.test.ts +6 -4
  89. package/src/scenarios/aiproviders-selfhosted-shape.test.ts +15 -17
  90. package/src/scenarios/aiproviders-speechsynth-shape.test.ts +6 -8
  91. package/src/scenarios/aiproviders-subscription-scope.test.ts +7 -8
  92. package/src/scenarios/anonymous-actor-audit-opaque.test.ts +9 -8
  93. package/src/scenarios/anonymous-actor-default-deny.test.ts +10 -9
  94. package/src/scenarios/anonymous-actor-egress-guarded.test.ts +6 -5
  95. package/src/scenarios/anonymous-actor-no-secret-reach.test.ts +7 -6
  96. package/src/scenarios/anonymous-actor-shape.test.ts +17 -19
  97. package/src/scenarios/anonymous-actor-write-gated.test.ts +9 -8
  98. package/src/scenarios/append-ordering.test.ts +7 -5
  99. package/src/scenarios/approval-gate-events.test.ts +4 -3
  100. package/src/scenarios/approval-gate-flow.test.ts +4 -3
  101. package/src/scenarios/approval-payload.test.ts +5 -4
  102. package/src/scenarios/artifact-auth.test.ts +7 -6
  103. package/src/scenarios/artifact-type-pack-install.test.ts +6 -6
  104. package/src/scenarios/artifact-type-pack-manifest-validation.test.ts +9 -8
  105. package/src/scenarios/artifact-type-registration-source.test.ts +20 -20
  106. package/src/scenarios/artifact-type-store-emission.test.ts +15 -18
  107. package/src/scenarios/artifact-type-store-without-render.test.ts +4 -4
  108. package/src/scenarios/audit-log-integrity.test.ts +8 -6
  109. package/src/scenarios/auth-api-key-rotation.test.ts +11 -9
  110. package/src/scenarios/auth-mtls.test.ts +22 -20
  111. package/src/scenarios/auth-oauth2-client-credentials.test.ts +16 -14
  112. package/src/scenarios/auth-oidc-user-bearer.test.ts +26 -24
  113. package/src/scenarios/auth-saml-profile.test.ts +14 -12
  114. package/src/scenarios/auth-scim-profile.test.ts +3 -2
  115. package/src/scenarios/auth-subject-link-key-class.test.ts +8 -7
  116. package/src/scenarios/auth-subject-link.test.ts +11 -10
  117. package/src/scenarios/auth.test.ts +5 -4
  118. package/src/scenarios/authorization-fail-closed.test.ts +3 -2
  119. package/src/scenarios/authorization-roles-shape.test.ts +9 -7
  120. package/src/scenarios/blob-cross-tenant-isolation.test.ts +8 -6
  121. package/src/scenarios/blob-presign-expiry.test.ts +12 -10
  122. package/src/scenarios/blob-roundtrip.test.ts +0 -0
  123. package/src/scenarios/budget-enforcement.test.ts +15 -14
  124. package/src/scenarios/budget-policy-shape.test.ts +18 -19
  125. package/src/scenarios/bulk-cancel.test.ts +9 -8
  126. package/src/scenarios/byok-auth-modes.test.ts +13 -14
  127. package/src/scenarios/byok-roundtrip.test.ts +12 -10
  128. package/src/scenarios/cache-cross-tenant-isolation.test.ts +8 -6
  129. package/src/scenarios/cache-ttl-expiry.test.ts +7 -5
  130. package/src/scenarios/callai-multimodal.test.ts +5 -3
  131. package/src/scenarios/cancellation.test.ts +6 -5
  132. package/src/scenarios/cap-breach.test.ts +15 -14
  133. package/src/scenarios/capability-arm-witness.test.ts +5 -3
  134. package/src/scenarios/certification-bundle-non-vacuous.test.ts +20 -19
  135. package/src/scenarios/certification-bundle-redaction.test.ts +11 -10
  136. package/src/scenarios/certification-bundle-v2.test.ts +11 -10
  137. package/src/scenarios/chain-compensation-expansion.test.ts +14 -13
  138. package/src/scenarios/chain-produced-var-roundtrip.test.ts +13 -14
  139. package/src/scenarios/chain-subchain-cycle-rejected.test.ts +9 -10
  140. package/src/scenarios/chain-subchain-fanout.test.ts +8 -9
  141. package/src/scenarios/chain-subchain-sibling.test.ts +14 -16
  142. package/src/scenarios/channel-presence-behavioral.test.ts +9 -7
  143. package/src/scenarios/channel-presence-shape.test.ts +11 -12
  144. package/src/scenarios/channel-ttl.test.ts +6 -5
  145. package/src/scenarios/chat-card-pack-execution.test.ts +4 -4
  146. package/src/scenarios/chat-card-pack-manifest-validation.test.ts +9 -8
  147. package/src/scenarios/commitment-fired.test.ts +6 -5
  148. package/src/scenarios/compensation-behavior.test.ts +24 -23
  149. package/src/scenarios/compensation-recovery.test.ts +28 -27
  150. package/src/scenarios/configurable-schema.test.ts +8 -6
  151. package/src/scenarios/conformance-advertised-seam-required.test.ts +6 -5
  152. package/src/scenarios/conformance-execution-witness.test.ts +9 -8
  153. package/src/scenarios/connection-pack-apihosts.test.ts +19 -17
  154. package/src/scenarios/connection-pack-manifest-valid.test.ts +12 -11
  155. package/src/scenarios/connection-pack-no-credential-material.test.ts +8 -6
  156. package/src/scenarios/connection-pack-reach-exclusive.test.ts +5 -4
  157. package/src/scenarios/connection-pack-write-reconsent.test.ts +6 -4
  158. package/src/scenarios/connection-provider-resolution.test.ts +18 -16
  159. package/src/scenarios/connector-manifest-validity.test.ts +8 -7
  160. package/src/scenarios/context-budget-transcript-bound.test.ts +17 -15
  161. package/src/scenarios/context-summarization-replay.test.ts +14 -12
  162. package/src/scenarios/contract-provenance.test.ts +18 -18
  163. package/src/scenarios/conversation-turn-model-provenance-shape.test.ts +14 -15
  164. package/src/scenarios/conversationCapabilityNegotiation.test.ts +2 -1
  165. package/src/scenarios/conversationLifecycle.test.ts +2 -1
  166. package/src/scenarios/conversationReplayDeterminism.test.ts +4 -2
  167. package/src/scenarios/conversationVsLegacySuspend.test.ts +2 -1
  168. package/src/scenarios/core-standard-profile.test.ts +8 -9
  169. package/src/scenarios/cost-attribution.test.ts +23 -21
  170. package/src/scenarios/credential-payload-redaction.test.ts +4 -3
  171. package/src/scenarios/credentials-capability-shape.test.ts +5 -4
  172. package/src/scenarios/cross-engine-append-behavior.test.ts +11 -10
  173. package/src/scenarios/cross-engine-append-ordering.test.ts +4 -3
  174. package/src/scenarios/cross-host-ancestry-endpoint.test.ts +11 -10
  175. package/src/scenarios/cross-host-causation-shape.test.ts +7 -6
  176. package/src/scenarios/cross-workspace-isolation.test.ts +4 -3
  177. package/src/scenarios/data-residency-admission.test.ts +15 -14
  178. package/src/scenarios/deadletter-capability-shape.test.ts +6 -4
  179. package/src/scenarios/deadletter-retry-exhaustion.test.ts +4 -3
  180. package/src/scenarios/debug-bundle-truncation.test.ts +9 -7
  181. package/src/scenarios/debugBundle.test.ts +25 -23
  182. package/src/scenarios/discovery-families-view.test.ts +5 -4
  183. package/src/scenarios/discovery.test.ts +30 -29
  184. package/src/scenarios/dispatch-cross-worker-handoff.test.ts +10 -8
  185. package/src/scenarios/dispatch-fanout-parallel.test.ts +24 -22
  186. package/src/scenarios/dispatch-input-mapping.test.ts +12 -10
  187. package/src/scenarios/dispatch-output-mapping.test.ts +9 -7
  188. package/src/scenarios/dispatch-per-item-input.test.ts +22 -20
  189. package/src/scenarios/dispatchLoop.test.ts +3 -2
  190. package/src/scenarios/distillation-index-roundtrip.test.ts +3 -3
  191. package/src/scenarios/distillation-secret-carryforward.test.ts +2 -2
  192. package/src/scenarios/distillation-shape.test.ts +4 -4
  193. package/src/scenarios/distillation-stable-archive.test.ts +6 -6
  194. package/src/scenarios/distillation-token-budget.test.ts +5 -5
  195. package/src/scenarios/durability-poison-exhaustion.test.ts +7 -6
  196. package/src/scenarios/egress-audience-binding.test.ts +11 -10
  197. package/src/scenarios/egress-decision-content-free.test.ts +6 -5
  198. package/src/scenarios/egress-provenance-shape.test.ts +17 -18
  199. package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +27 -25
  200. package/src/scenarios/envelope-nl-to-format-engaged.test.ts +19 -17
  201. package/src/scenarios/envelope-reasoning-secret-redaction.test.ts +28 -26
  202. package/src/scenarios/envelope-reasoning-shape.test.ts +19 -17
  203. package/src/scenarios/envelope-recovery-applied.test.ts +24 -22
  204. package/src/scenarios/envelope-refusal-shape.test.ts +31 -29
  205. package/src/scenarios/envelope-rendering-hint.test.ts +5 -4
  206. package/src/scenarios/envelope-retry-attempted.test.ts +33 -31
  207. package/src/scenarios/envelope-retry-exhausted.test.ts +22 -20
  208. package/src/scenarios/envelope-tier-one-subset-static.test.ts +9 -7
  209. package/src/scenarios/envelope-truncated.test.ts +19 -17
  210. package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +19 -17
  211. package/src/scenarios/envelope-variant-discriminator-static.test.ts +4 -3
  212. package/src/scenarios/errors.test.ts +20 -19
  213. package/src/scenarios/eventOrdering.test.ts +16 -14
  214. package/src/scenarios/exec-not-protocol-tier.test.ts +5 -7
  215. package/src/scenarios/experimental-tier-shape.test.ts +17 -15
  216. package/src/scenarios/export-bundle-portability.test.ts +17 -17
  217. package/src/scenarios/failure-path.test.ts +7 -6
  218. package/src/scenarios/feedback-capability-shape.test.ts +4 -3
  219. package/src/scenarios/feedback-correction-redaction.test.ts +2 -1
  220. package/src/scenarios/feedback-cross-tenant-isolation.test.ts +2 -1
  221. package/src/scenarios/feedback-fork-not-copied.test.ts +3 -2
  222. package/src/scenarios/feedback-on-terminal-run.test.ts +3 -2
  223. package/src/scenarios/feedback-record-and-list.test.ts +2 -1
  224. package/src/scenarios/feedback-unsupported-501.test.ts +2 -1
  225. package/src/scenarios/fixtures-gating.test.ts +29 -28
  226. package/src/scenarios/fixtures-valid.test.ts +16 -15
  227. package/src/scenarios/form-content-instantiation.test.ts +15 -14
  228. package/src/scenarios/frontend-plugin-packs.test.ts +29 -27
  229. package/src/scenarios/fs-path-traversal.test.ts +14 -12
  230. package/src/scenarios/goal-standing-continuation.test.ts +21 -21
  231. package/src/scenarios/grpc-transport.test.ts +9 -7
  232. package/src/scenarios/heartbeat-capability-shape.test.ts +3 -3
  233. package/src/scenarios/heartbeat-fires-once-per-tick.test.ts +2 -2
  234. package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +3 -3
  235. package/src/scenarios/heartbeat-runtime-bound.test.ts +2 -2
  236. package/src/scenarios/highConcurrency.test.ts +14 -13
  237. package/src/scenarios/host-callback-declaration.test.ts +8 -7
  238. package/src/scenarios/http-client-ssrf.test.ts +7 -5
  239. package/src/scenarios/i18n-negotiation.test.ts +14 -12
  240. package/src/scenarios/idempotency-concurrent-claim.test.ts +14 -13
  241. package/src/scenarios/idempotency-key-determinism.test.ts +20 -18
  242. package/src/scenarios/idempotency.test.ts +8 -7
  243. package/src/scenarios/idempotencyRetry.test.ts +13 -11
  244. package/src/scenarios/identity-owner-shape.test.ts +6 -5
  245. package/src/scenarios/identity-passthrough.test.ts +4 -3
  246. package/src/scenarios/interrupt-approval.test.ts +6 -5
  247. package/src/scenarios/interrupt-approver-routing.test.ts +15 -15
  248. package/src/scenarios/interrupt-auth-required-resume.test.ts +5 -3
  249. package/src/scenarios/interrupt-clarification.test.ts +4 -3
  250. package/src/scenarios/interrupt-external-event-correlation.test.ts +6 -5
  251. package/src/scenarios/interrupt-parent-child-cascade.test.ts +4 -3
  252. package/src/scenarios/interrupt-quorum-resolution.test.ts +5 -4
  253. package/src/scenarios/interrupt-token-matrix.test.ts +8 -6
  254. package/src/scenarios/interruptRace.test.ts +12 -10
  255. package/src/scenarios/kv-atomic-increment.test.ts +11 -9
  256. package/src/scenarios/kv-cas.test.ts +14 -12
  257. package/src/scenarios/kv-cross-tenant-isolation.test.ts +12 -10
  258. package/src/scenarios/kv-ttl-expiry.test.ts +7 -5
  259. package/src/scenarios/localized-content-delivery.test.ts +24 -26
  260. package/src/scenarios/maliciousManifest.test.ts +10 -8
  261. package/src/scenarios/mcp-2026-07-28-discover.test.ts +15 -14
  262. package/src/scenarios/mcp-cache-tenant-scope.test.ts +6 -5
  263. package/src/scenarios/mcp-current-auth-boundary.test.ts +7 -6
  264. package/src/scenarios/mcp-discoverability.test.ts +9 -7
  265. package/src/scenarios/mcp-extension-opacity.test.ts +7 -6
  266. package/src/scenarios/mcp-mrtr-roundtrip.test.ts +18 -17
  267. package/src/scenarios/mcp-server-elicitation-bridge.test.ts +13 -12
  268. package/src/scenarios/mcp-server-prompt-roundtrip.test.ts +11 -10
  269. package/src/scenarios/mcp-server-resource-roundtrip.test.ts +11 -10
  270. package/src/scenarios/mcp-server-sampling-bridge.test.ts +12 -11
  271. package/src/scenarios/mcp-server-tool-roundtrip.test.ts +14 -13
  272. package/src/scenarios/mcp-server-untrusted-args.test.ts +14 -13
  273. package/src/scenarios/mcp-stateless-request.test.ts +11 -10
  274. package/src/scenarios/mcp-tool-roundtrip.test.ts +4 -3
  275. package/src/scenarios/mcp-toolcall-redaction.test.ts +4 -3
  276. package/src/scenarios/mcp-version-negotiation.test.ts +15 -14
  277. package/src/scenarios/media-url-inline-cap.test.ts +21 -19
  278. package/src/scenarios/memory-attribution-emits-on-write.test.ts +5 -5
  279. package/src/scenarios/memory-attribution-no-content.test.ts +4 -4
  280. package/src/scenarios/memory-attribution-replay-stable.test.ts +4 -3
  281. package/src/scenarios/memory-attribution-shape.test.ts +4 -3
  282. package/src/scenarios/memory-attribution-tenant-scoped.test.ts +3 -3
  283. package/src/scenarios/memory-capability-model-shape.test.ts +14 -15
  284. package/src/scenarios/memory-compaction-event-emitted.test.ts +7 -6
  285. package/src/scenarios/memory-compaction-provenance-tag.test.ts +3 -2
  286. package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +7 -6
  287. package/src/scenarios/memory-consolidation-idempotent.test.ts +5 -4
  288. package/src/scenarios/memory-consolidation-shape.test.ts +9 -11
  289. package/src/scenarios/memory-degraded-projection.test.ts +10 -9
  290. package/src/scenarios/memory-injection-budget.test.ts +15 -14
  291. package/src/scenarios/metric-emission.test.ts +4 -3
  292. package/src/scenarios/model-capability-insufficient.test.ts +19 -17
  293. package/src/scenarios/model-capability-substituted.test.ts +20 -18
  294. package/src/scenarios/multi-agent-confidence-escalation.test.ts +12 -11
  295. package/src/scenarios/multi-agent-handoff-state-machine.test.ts +10 -9
  296. package/src/scenarios/multi-agent-memory-lifecycle.test.ts +11 -10
  297. package/src/scenarios/multi-node-ordering.test.ts +4 -3
  298. package/src/scenarios/multi-party-conversation-behavioral.test.ts +6 -6
  299. package/src/scenarios/multi-party-conversation-shape.test.ts +21 -23
  300. package/src/scenarios/multi-region-idempotency-behavior.test.ts +16 -15
  301. package/src/scenarios/multi-region-idempotency.test.ts +6 -5
  302. package/src/scenarios/node-failed-payload-shape.test.ts +5 -4
  303. package/src/scenarios/node-module-required-capabilities-shape.test.ts +10 -8
  304. package/src/scenarios/oauth-authorization-code-roundtrip.test.ts +5 -4
  305. package/src/scenarios/oauth-capability-shape.test.ts +5 -4
  306. package/src/scenarios/oauth-connector-redaction.test.ts +4 -3
  307. package/src/scenarios/openapi-resolved-paths.test.ts +6 -5
  308. package/src/scenarios/orchestratorConservativePath.test.ts +2 -1
  309. package/src/scenarios/orchestratorDispatch.test.ts +2 -1
  310. package/src/scenarios/orchestratorTermination.test.ts +2 -1
  311. package/src/scenarios/org-position-no-authority-escalation.test.ts +2 -2
  312. package/src/scenarios/otel-collector-canary-inspection.test.ts +8 -7
  313. package/src/scenarios/otel-emission-grpc.test.ts +3 -2
  314. package/src/scenarios/otel-emission.test.ts +6 -5
  315. package/src/scenarios/otel-trace-propagation-subworkflow.test.ts +7 -6
  316. package/src/scenarios/otel-trace-propagation.test.ts +2 -1
  317. package/src/scenarios/owner-subject-echo.test.ts +13 -12
  318. package/src/scenarios/owner-subject-shape.test.ts +11 -10
  319. package/src/scenarios/pack-manifest-extension-opacity.test.ts +8 -8
  320. package/src/scenarios/pack-registry-isolation.test.ts +4 -3
  321. package/src/scenarios/pack-registry-publish.test.ts +65 -63
  322. package/src/scenarios/pack-registry.test.ts +38 -36
  323. package/src/scenarios/pause-resume.test.ts +18 -16
  324. package/src/scenarios/policies.test.ts +20 -18
  325. package/src/scenarios/production-backpressure.test.ts +18 -16
  326. package/src/scenarios/production-retention-expiry.test.ts +8 -6
  327. package/src/scenarios/profile-discovery-core-alias.test.ts +13 -11
  328. package/src/scenarios/profileDerivation.test.ts +34 -33
  329. package/src/scenarios/prompt-all-four-kinds-events.test.ts +11 -9
  330. package/src/scenarios/prompt-composed-secret-redaction.test.ts +11 -9
  331. package/src/scenarios/prompt-composed-trust-marker.test.ts +10 -8
  332. package/src/scenarios/prompt-end-to-end-events.test.ts +17 -15
  333. package/src/scenarios/prompt-list-and-fetch.test.ts +16 -14
  334. package/src/scenarios/prompt-mutable-lifecycle.test.ts +13 -11
  335. package/src/scenarios/prompt-mutation-workspace-membership-enforced.test.ts +6 -4
  336. package/src/scenarios/prompt-pack-install.test.ts +14 -12
  337. package/src/scenarios/prompt-prefix-cache.test.ts +19 -17
  338. package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +11 -9
  339. package/src/scenarios/prompt-render-deterministic.test.ts +19 -17
  340. package/src/scenarios/prompt-resolution-chain-agent-intrinsic.test.ts +7 -5
  341. package/src/scenarios/prompt-resolution-chain-event.test.ts +12 -10
  342. package/src/scenarios/prompt-resolution-chain-fallback-cascade.test.ts +10 -8
  343. package/src/scenarios/prompt-resolution-chain-node-wins.test.ts +8 -6
  344. package/src/scenarios/prompt-template-shape.test.ts +30 -28
  345. package/src/scenarios/proposal-reviewable-learning.test.ts +19 -19
  346. package/src/scenarios/protocol-versions-array.test.ts +10 -9
  347. package/src/scenarios/provider-usage.test.ts +17 -15
  348. package/src/scenarios/providerPolicyEnforcement.test.ts +16 -14
  349. package/src/scenarios/purpose-propagation.test.ts +23 -21
  350. package/src/scenarios/queue-ack-nack-dlq.test.ts +12 -10
  351. package/src/scenarios/queue-cross-tenant-isolation.test.ts +8 -6
  352. package/src/scenarios/queue-publish-consume-roundtrip.test.ts +10 -8
  353. package/src/scenarios/rate-limit-envelope.test.ts +6 -5
  354. package/src/scenarios/redaction.test.ts +13 -11
  355. package/src/scenarios/redactionAdversarial.test.ts +11 -9
  356. package/src/scenarios/registry-public.test.ts +12 -11
  357. package/src/scenarios/replay-divergence-at-refusal.test.ts +16 -15
  358. package/src/scenarios/replay-fanout-suppression.test.ts +16 -15
  359. package/src/scenarios/replay-fork-arbitrary.test.ts +24 -23
  360. package/src/scenarios/replay-fork.test.ts +20 -19
  361. package/src/scenarios/replay-llm-cache-key-portable.test.ts +11 -9
  362. package/src/scenarios/replay-llm-cache-key.test.ts +22 -21
  363. package/src/scenarios/replay-observable-sequence-determinism.test.ts +4 -3
  364. package/src/scenarios/replay-retention-expiry.test.ts +11 -9
  365. package/src/scenarios/replay-side-effect-suppression.test.ts +21 -19
  366. package/src/scenarios/replayDeterminism.test.ts +13 -12
  367. package/src/scenarios/requirement-ledger.test.ts +15 -14
  368. package/src/scenarios/restart-during-run.test.ts +3 -2
  369. package/src/scenarios/route-coverage.test.ts +20 -19
  370. package/src/scenarios/run-diff.test.ts +22 -20
  371. package/src/scenarios/run-execution-bounds-shape.test.ts +14 -12
  372. package/src/scenarios/run-transport-economy.test.ts +13 -11
  373. package/src/scenarios/runner-ledger.test.ts +17 -16
  374. package/src/scenarios/runs-lifecycle.test.ts +7 -6
  375. package/src/scenarios/runtime-capabilities.test.ts +12 -10
  376. package/src/scenarios/runtime-requires-install-gate.test.ts +8 -8
  377. package/src/scenarios/runtime-requires-shape.test.ts +7 -6
  378. package/src/scenarios/safefetch-behavior.test.ts +22 -21
  379. package/src/scenarios/safefetch-live-audit.test.ts +14 -13
  380. package/src/scenarios/sandbox-memory-cap.test.ts +2 -1
  381. package/src/scenarios/sandbox-mvp-behavior.test.ts +24 -23
  382. package/src/scenarios/sandbox-no-host-fs-escape.test.ts +3 -2
  383. package/src/scenarios/sandbox-timeout-cap.test.ts +2 -1
  384. package/src/scenarios/sandbox-wasm-isolation.test.ts +14 -15
  385. package/src/scenarios/sandbox-wasm-timeout.test.ts +5 -6
  386. package/src/scenarios/scheduling-capability-shape.test.ts +8 -6
  387. package/src/scenarios/scheduling-cron-fires-once.test.ts +8 -6
  388. package/src/scenarios/search-bm25-roundtrip.test.ts +8 -6
  389. package/src/scenarios/secret-leakage-otel-attribute.test.ts +22 -20
  390. package/src/scenarios/self-hosted-runner.test.ts +26 -24
  391. package/src/scenarios/semantic-digest-vectors.test.ts +8 -7
  392. package/src/scenarios/speech-synthesis-roundtrip.test.ts +9 -7
  393. package/src/scenarios/speech-synthesis-unadvertised.test.ts +5 -3
  394. package/src/scenarios/sql-injection-rejection.test.ts +8 -6
  395. package/src/scenarios/sql-transaction-atomicity.test.ts +10 -8
  396. package/src/scenarios/staleClaim.test.ts +5 -4
  397. package/src/scenarios/stream-modes-buffer.test.ts +8 -7
  398. package/src/scenarios/stream-modes-mixed.test.ts +10 -9
  399. package/src/scenarios/stream-modes.test.ts +12 -11
  400. package/src/scenarios/stream-subscribe-from-beginning.test.ts +11 -9
  401. package/src/scenarios/stream-text-fixture.test.ts +14 -13
  402. package/src/scenarios/streamReconnect.test.ts +13 -11
  403. package/src/scenarios/strict-behavior-gate.test.ts +9 -8
  404. package/src/scenarios/subrun-approval-fail-closed.test.ts +2 -2
  405. package/src/scenarios/subrun-approval-gate.test.ts +3 -3
  406. package/src/scenarios/subrun-attestation-shape.test.ts +2 -2
  407. package/src/scenarios/subrun-checksum-stable.test.ts +4 -4
  408. package/src/scenarios/subworkflow-input-mapping.test.ts +16 -14
  409. package/src/scenarios/subworkflow.test.ts +10 -9
  410. package/src/scenarios/table-cross-tenant-isolation.test.ts +8 -6
  411. package/src/scenarios/table-cursor-pagination.test.ts +8 -6
  412. package/src/scenarios/table-schema-enforcement.test.ts +7 -5
  413. package/src/scenarios/test-seam-unauthenticated.test.ts +2 -2
  414. package/src/scenarios/tool-catalog-compact-projection.test.ts +10 -8
  415. package/src/scenarios/tool-catalog-projection.test.ts +11 -9
  416. package/src/scenarios/tool-descriptor-shape.test.ts +14 -15
  417. package/src/scenarios/tool-hooks-authorization-fail-closed.test.ts +3 -3
  418. package/src/scenarios/tool-hooks-content-free.test.ts +4 -4
  419. package/src/scenarios/tool-hooks-failure-honesty.test.ts +4 -4
  420. package/src/scenarios/tool-hooks-rate-limit.test.ts +2 -2
  421. package/src/scenarios/tool-hooks-secret-redaction.test.ts +2 -2
  422. package/src/scenarios/tool-hooks-shape.test.ts +3 -3
  423. package/src/scenarios/tool-session-lifecycle.test.ts +14 -13
  424. package/src/scenarios/trigger-bridge-delivery.test.ts +14 -14
  425. package/src/scenarios/trigger-bridge-shape.test.ts +19 -20
  426. package/src/scenarios/trigger-ingestion.test.ts +19 -17
  427. package/src/scenarios/trigger-stream-cdc-sources.test.ts +16 -14
  428. package/src/scenarios/v2-approver-enforced.test.ts +97 -0
  429. package/src/scenarios/v2-assurance-downgrade-audited.test.ts +75 -0
  430. package/src/scenarios/v2-bundle-v3-signed.test.ts +96 -0
  431. package/src/scenarios/v2-capabilities-root-closed.test.ts +63 -0
  432. package/src/scenarios/v2-capability-record-shape.test.ts +104 -0
  433. package/src/scenarios/v2-chain-pin-exact.test.ts +118 -0
  434. package/src/scenarios/v2-coherence-not-in-bundle.test.ts +98 -0
  435. package/src/scenarios/v2-compensation-read-projection.test.ts +85 -0
  436. package/src/scenarios/v2-configurable-closed.test.ts +67 -0
  437. package/src/scenarios/v2-dual-stack-negotiation.test.ts +118 -0
  438. package/src/scenarios/v2-effect-identity-business-key.test.ts +132 -0
  439. package/src/scenarios/v2-effect-seam-manifest.test.ts +163 -0
  440. package/src/scenarios/v2-enum-growth-rule.test.ts +69 -0
  441. package/src/scenarios/v2-era-key.test.ts +86 -0
  442. package/src/scenarios/v2-error-registry.test.ts +89 -0
  443. package/src/scenarios/v2-event-type-closed.test.ts +97 -0
  444. package/src/scenarios/v2-fork-a-v1-run.test.ts +109 -0
  445. package/src/scenarios/v2-form-when-reuses-edge-conditions.test.ts +70 -0
  446. package/src/scenarios/v2-header-scheme.test.ts +67 -0
  447. package/src/scenarios/v2-id-grammar.test.ts +77 -0
  448. package/src/scenarios/v2-idempotency-key-grammar.test.ts +65 -0
  449. package/src/scenarios/v2-interrupt-token-scheme.test.ts +55 -0
  450. package/src/scenarios/v2-lane-issuer-advertised.test.ts +62 -0
  451. package/src/scenarios/v2-legacy-profiles-absent.test.ts +78 -0
  452. package/src/scenarios/v2-manifest-ceiling-refused.test.ts +130 -0
  453. package/src/scenarios/v2-manifest-hatch-carried.test.ts +120 -0
  454. package/src/scenarios/v2-min-client-version.test.ts +48 -0
  455. package/src/scenarios/v2-minimum-version-refused.test.ts +141 -0
  456. package/src/scenarios/v2-mrtr-rounds-ceiling.test.ts +95 -0
  457. package/src/scenarios/v2-negotiation-authenticated.test.ts +125 -0
  458. package/src/scenarios/v2-negotiation-decided-emitted.test.ts +149 -0
  459. package/src/scenarios/v2-no-transport-advertisement.test.ts +57 -0
  460. package/src/scenarios/v2-owner-subject-required.test.ts +72 -0
  461. package/src/scenarios/v2-pack-isolation.test.ts +147 -0
  462. package/src/scenarios/v2-payload-registry-closed.test.ts +110 -0
  463. package/src/scenarios/v2-peer-dependency-declared.test.ts +132 -0
  464. package/src/scenarios/v2-pinned-run-disposition.test.ts +124 -0
  465. package/src/scenarios/v2-poll-cursor-v2.test.ts +114 -0
  466. package/src/scenarios/v2-preferred-version-default.test.ts +83 -0
  467. package/src/scenarios/v2-profiles-derived-only.test.ts +70 -0
  468. package/src/scenarios/v2-provider-conflict.test.ts +115 -0
  469. package/src/scenarios/v2-refresh-sla.test.ts +78 -0
  470. package/src/scenarios/v2-relaxation-recorded.test.ts +134 -0
  471. package/src/scenarios/v2-revocation-honored.test.ts +66 -0
  472. package/src/scenarios/v2-subject-link-record.test.ts +102 -0
  473. package/src/scenarios/v2-unmapped-type-refused.test.ts +95 -0
  474. package/src/scenarios/v2-v1-events-translated.test.ts +105 -0
  475. package/src/scenarios/v2-v1-signed-webhook-accepted.test.ts +109 -0
  476. package/src/scenarios/v2-webhook-durable-delivery.test.ts +238 -0
  477. package/src/scenarios/v2-well-known-one-resource.test.ts +129 -0
  478. package/src/scenarios/vector-knn-roundtrip.test.ts +9 -7
  479. package/src/scenarios/verifier-gating.test.ts +8 -6
  480. package/src/scenarios/version-fold.test.ts +9 -8
  481. package/src/scenarios/version-negotiation.test.ts +12 -11
  482. package/src/scenarios/voice-bargein-no-partial-leak.test.ts +8 -6
  483. package/src/scenarios/voice-event-payloads-shape.test.ts +10 -11
  484. package/src/scenarios/voice-interim-not-durable.test.ts +7 -5
  485. package/src/scenarios/voice-streamref-tenant-bound.test.ts +5 -3
  486. package/src/scenarios/voice-synthesis-streaming.test.ts +11 -9
  487. package/src/scenarios/voice-transcription-streaming.test.ts +8 -6
  488. package/src/scenarios/voice-transcription-unadvertised.test.ts +5 -3
  489. package/src/scenarios/wasm-pack-abi-version-rejection.test.ts +3 -2
  490. package/src/scenarios/wasm-pack-invoke-completed.test.ts +3 -2
  491. package/src/scenarios/wasm-pack-invoke-suspended.test.ts +3 -2
  492. package/src/scenarios/wasm-pack-load.test.ts +4 -3
  493. package/src/scenarios/wasm-pack-memory-cap.test.ts +5 -4
  494. package/src/scenarios/wasm-pack-replay-determinism.test.ts +2 -1
  495. package/src/scenarios/webhook-negative.test.ts +11 -9
  496. package/src/scenarios/webhook-receiver-adversarial.test.ts +8 -7
  497. package/src/scenarios/webhook-sig-algorithm.test.ts +5 -3
  498. package/src/scenarios/webhook-signed-delivery.test.ts +16 -15
  499. package/src/scenarios/webhook-tenant-isolation.test.ts +16 -14
  500. package/src/scenarios/workflow-chain-deferred-parameters.test.ts +28 -30
  501. package/src/scenarios/workflow-chain-expansion.test.ts +21 -20
  502. package/src/scenarios/workflow-chain-host-expansion.test.ts +21 -20
  503. package/src/scenarios/workflow-chain-pack-manifest-validation.test.ts +14 -12
  504. package/src/scenarios/workflow-chain-pack-signature-verification.test.ts +5 -4
  505. package/src/scenarios/workflow-chain-unresolvable-typeid.test.ts +9 -8
  506. package/src/scenarios/workflow-primary-output-annotation.test.ts +7 -6
  507. package/src/scenarios/workflow-variable-format.test.ts +24 -24
  508. package/src/scenarios/workload-identity-behavior.test.ts +15 -13
  509. package/src/scenarios/workload-identity-chain-bounds.test.ts +18 -17
  510. package/src/scenarios/workspace-behavior.test.ts +19 -18
  511. package/src/scenarios/workspace-capability-shape.test.ts +3 -2
  512. package/src/scenarios/workspace-cross-tenant-isolation-blackbox.test.ts +6 -5
  513. package/src/scenarios/workspace-cross-tenant-isolation.test.ts +7 -6
  514. package/src/scenarios/x-openwop-form-pack-manifest.test.ts +8 -7
  515. package/src/setup.ts +44 -6
  516. package/vitest.config.ts +5 -1
  517. package/api/.redocly.lint-ignore.yaml +0 -22
  518. package/api/asyncapi.yaml +0 -834
  519. package/api/grpc/openwop.proto +0 -251
  520. package/api/openapi.yaml +0 -2693
  521. package/api/redocly.yaml +0 -23
  522. package/schemas/README.md +0 -144
  523. package/schemas/a2a-task-state.schema.json +0 -78
  524. package/schemas/a2ui-surface-delta-frame.schema.json +0 -48
  525. package/schemas/agent-deployment-transition.schema.json +0 -49
  526. package/schemas/agent-deployment.schema.json +0 -54
  527. package/schemas/agent-eval-suite.schema.json +0 -140
  528. package/schemas/agent-inventory-response.schema.json +0 -115
  529. package/schemas/agent-manifest.schema.json +0 -156
  530. package/schemas/agent-org-chart.schema.json +0 -82
  531. package/schemas/agent-ref.schema.json +0 -63
  532. package/schemas/agent-roster-entry.schema.json +0 -81
  533. package/schemas/agent-roster-response.schema.json +0 -21
  534. package/schemas/ai-envelope.schema.json +0 -134
  535. package/schemas/annotation-create.schema.json +0 -37
  536. package/schemas/annotation.schema.json +0 -56
  537. package/schemas/artifact-type-pack-manifest.schema.json +0 -244
  538. package/schemas/audit-verify-result.schema.json +0 -90
  539. package/schemas/budget-policy.schema.json +0 -18
  540. package/schemas/capabilities.schema.json +0 -4160
  541. package/schemas/certification-bundle-v2.schema.json +0 -118
  542. package/schemas/channel-presence-payload.schema.json +0 -41
  543. package/schemas/channel-written-payload.schema.json +0 -55
  544. package/schemas/chat-card-pack-manifest.schema.json +0 -253
  545. package/schemas/compact-tool-descriptor.schema.json +0 -51
  546. package/schemas/compensation-policy.schema.json +0 -64
  547. package/schemas/conformance-certification-bundle.schema.json +0 -86
  548. package/schemas/connection-pack-manifest.schema.json +0 -353
  549. package/schemas/conversation-event.schema.json +0 -168
  550. package/schemas/conversation-turn.schema.json +0 -117
  551. package/schemas/core-conformance-mock-agent-config.schema.json +0 -152
  552. package/schemas/credential-provenance.schema.json +0 -18
  553. package/schemas/credential-reference.schema.json +0 -21
  554. package/schemas/debug-bundle.schema.json +0 -196
  555. package/schemas/dispatch-config.schema.json +0 -112
  556. package/schemas/envelopes/clarification.request.schema.json +0 -52
  557. package/schemas/envelopes/error.schema.json +0 -30
  558. package/schemas/envelopes/media.audio.schema.json +0 -38
  559. package/schemas/envelopes/media.file.schema.json +0 -37
  560. package/schemas/envelopes/media.image.schema.json +0 -33
  561. package/schemas/envelopes/schema.request.schema.json +0 -26
  562. package/schemas/envelopes/schema.response.schema.json +0 -22
  563. package/schemas/envelopes/ui.a2ui-surface.schema.json +0 -154
  564. package/schemas/error-envelope.schema.json +0 -25
  565. package/schemas/eval-summary.schema.json +0 -92
  566. package/schemas/export-bundle.schema.json +0 -66
  567. package/schemas/form-content-pack-manifest.schema.json +0 -243
  568. package/schemas/frontend-plugin-manifest.schema.json +0 -109
  569. package/schemas/goal.schema.json +0 -104
  570. package/schemas/heartbeat-evaluated.schema.json +0 -14
  571. package/schemas/heartbeat-state-changed.schema.json +0 -14
  572. package/schemas/localized-content-language-settings.schema.json +0 -26
  573. package/schemas/localized-content-page-response.schema.json +0 -60
  574. package/schemas/localized-content-page.schema.json +0 -62
  575. package/schemas/localized-content-section.schema.json +0 -51
  576. package/schemas/memory-entry.schema.json +0 -36
  577. package/schemas/memory-list-options.schema.json +0 -37
  578. package/schemas/node-pack-manifest.schema.json +0 -654
  579. package/schemas/orchestrator-decision.schema.json +0 -90
  580. package/schemas/org-chart-responsibility-view.schema.json +0 -26
  581. package/schemas/pack-lockfile.schema.json +0 -108
  582. package/schemas/prompt-kind.schema.json +0 -8
  583. package/schemas/prompt-pack-manifest.schema.json +0 -117
  584. package/schemas/prompt-ref.schema.json +0 -40
  585. package/schemas/prompt-template.schema.json +0 -149
  586. package/schemas/proposal.schema.json +0 -84
  587. package/schemas/registry-version-manifest.schema.json +0 -208
  588. package/schemas/residency.schema.json +0 -16
  589. package/schemas/run-ancestry-response.schema.json +0 -54
  590. package/schemas/run-diff-response.schema.json +0 -64
  591. package/schemas/run-event-payloads.schema.json +0 -4452
  592. package/schemas/run-event.schema.json +0 -211
  593. package/schemas/run-options.schema.json +0 -80
  594. package/schemas/run-orchestrator-decided-event.schema.json +0 -20
  595. package/schemas/run-snapshot.schema.json +0 -148
  596. package/schemas/security-advisory.schema.json +0 -109
  597. package/schemas/self-hosted-runner-dispatch-frame.schema.json +0 -79
  598. package/schemas/self-hosted-runner-registration.schema.json +0 -53
  599. package/schemas/self-hosted-runner-result-frame.schema.json +0 -38
  600. package/schemas/subject.schema.json +0 -56
  601. package/schemas/suspend-request.schema.json +0 -207
  602. package/schemas/tool-descriptor.schema.json +0 -63
  603. package/schemas/trigger-event.schema.json +0 -222
  604. package/schemas/trigger-subscription-registration.schema.json +0 -67
  605. package/schemas/trigger-subscription.schema.json +0 -26
  606. package/schemas/ui-plugin-message.schema.json +0 -90
  607. package/schemas/workflow-chain-pack-manifest.schema.json +0 -615
  608. package/schemas/workflow-definition.schema.json +0 -850
  609. package/schemas/workload-identity.schema.json +0 -79
  610. package/schemas/workspace-file-create.schema.json +0 -20
  611. package/schemas/workspace-file.schema.json +0 -39
@@ -28,8 +28,7 @@ import addFormats from 'ajv-formats';
28
28
  import { SCHEMAS_DIR } from '../lib/paths.js';
29
29
  import { behaviorGate } from '../lib/behavior-gate.js';
30
30
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
31
-
32
- const cite = (section: string, requirement: string): string => `${section} — ${requirement}`;
31
+ import { req } from '../lib/requirement-ids.js';
33
32
  const CAPS = join(SCHEMAS_DIR, 'capabilities.schema.json');
34
33
  const MANIFEST = join(SCHEMAS_DIR, 'workflow-chain-pack-manifest.schema.json');
35
34
 
@@ -40,20 +39,20 @@ function loadSchema(path: string): Record<string, unknown> {
40
39
  describe('chain-subchain-fanout §A: capability + manifest shape (RFC 0133, always-on)', () => {
41
40
  it('capabilities.schema.json §workflowChainPacks.subChains requires supported:boolean + maxDepth default 8', () => {
42
41
  const raw = readFileSync(CAPS, 'utf8');
43
- expect(raw.includes('"subChains"'), cite('capabilities §workflowChainPacks', 'the subChains block MUST exist')).toBe(
42
+ expect(raw.includes('"subChains"'), req('openwop.it.chain-subchain-fanout.capabilities-schema-json-workflowchainpacks-subchains-requires-supported-boolean', 'capabilities §workflowChainPacks', 'the subChains block MUST exist')).toBe(
44
43
  true,
45
44
  );
46
45
  const schema = loadSchema(CAPS);
47
46
  // The subChains sub-block MUST be present somewhere in the workflowChainPacks family.
48
47
  expect(
49
48
  JSON.stringify(schema).includes('"subChains"'),
50
- cite('capabilities §subChains', 'declared in the capabilities schema'),
49
+ req('openwop.it.chain-subchain-fanout.capabilities-schema-json-workflowchainpacks-subchains-requires-supported-boolean', 'capabilities §subChains', 'declared in the capabilities schema'),
51
50
  ).toBe(true);
52
51
  expect(
53
52
  raw.includes('sub_chain_unsupported'),
54
- cite('capabilities §subChains', 'the description MUST cite the sub_chain_unsupported refusal'),
53
+ req('openwop.it.chain-subchain-fanout.capabilities-schema-json-workflowchainpacks-subchains-requires-supported-boolean', 'capabilities §subChains', 'the description MUST cite the sub_chain_unsupported refusal'),
55
54
  ).toBe(true);
56
- expect(raw.includes('"default": 8'), cite('capabilities §subChains.maxDepth', 'RECOMMENDED default 8')).toBe(true);
55
+ expect(raw.includes('"default": 8'), req('openwop.it.chain-subchain-fanout.capabilities-schema-json-workflowchainpacks-subchains-requires-supported-boolean', 'capabilities §subChains.maxDepth', 'RECOMMENDED default 8')).toBe(true);
57
56
  });
58
57
 
59
58
  it('manifest schema accepts a core.dispatch fan-out over a subChainRef worker', () => {
@@ -93,7 +92,7 @@ describe('chain-subchain-fanout §A: capability + manifest shape (RFC 0133, alwa
93
92
  },
94
93
  ],
95
94
  };
96
- expect(validate(pack), cite('manifest §subChains', `a subChainRef fan-out validates: ${ajv.errorsText(validate.errors)}`)).toBe(
95
+ expect(validate(pack), req('openwop.it.chain-subchain-fanout.manifest-schema-accepts-a-core-dispatch-fan-out-over-a-subchainref-worker', 'manifest §subChains', `a subChainRef fan-out validates: ${ajv.errorsText(validate.errors)}`)).toBe(
97
96
  true,
98
97
  );
99
98
  });
@@ -120,7 +119,7 @@ describe('chain-subchain-fanout §A: capability + manifest shape (RFC 0133, alwa
120
119
  };
121
120
  expect(
122
121
  validate(pack),
123
- cite('manifest §config not-guard', 'a chain MUST NOT pin a concrete config.workflowId'),
122
+ req('openwop.it.chain-subchain-fanout.manifest-schema-rejects-a-concrete-config-workflowid-inside-a-fragment-the-1-2-n', 'manifest §config not-guard', 'a chain MUST NOT pin a concrete config.workflowId'),
124
123
  ).toBe(false);
125
124
  });
126
125
  });
@@ -134,6 +133,6 @@ describe('chain-subchain-fanout §B: host child fan-out (RFC 0133, capability-ga
134
133
  // invariant `sub-chain-child-tenant-scoped` (child owned by parent's tenant).
135
134
  // The from-chain response MUST carry the §1.3 contract: { workflowId,
136
135
  // subChainWorkflowIds[] (tenant-scoped, deduped), nodeCount }.
137
- expect(wcp?.subChains?.supported, 'host advertising subChains.supported implements child fan-out').toBe(true);
136
+ expect(wcp?.subChains?.supported, req('openwop.it.chain-subchain-fanout.fans-out-n-child-runs-over-a-subchainref-worker-returns-the-from-chain-contract', 'RFC 0133 §1.2', 'host advertising subChains.supported implements child fan-out')).toBe(true);
138
137
  });
139
138
  });
@@ -30,9 +30,7 @@ import {
30
30
  mintChildWorkflowId,
31
31
  type WorkflowChain,
32
32
  } from '../lib/workflow-chain-expansion.js';
33
-
34
- /** Server-free assertion-message helper (mirrors driver.describe without OPENWOP_BASE_URL). */
35
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
33
+ import { req } from '../lib/requirement-ids.js';
36
34
  const SPEC = 'workflow-chain-packs.md §"Sub-chain composition (RFC 0133)"';
37
35
 
38
36
  /** A leaf child chain — one plain node, no further composition. */
@@ -83,53 +81,53 @@ const ctx = (tenantId = 'tenant-a') => ({
83
81
  describe('chain-subchain-sibling: co-registration (RFC 0133 §1, server-free)', () => {
84
82
  it('co-registers the referenced sibling as its own workflow', () => {
85
83
  const { children } = expandChainTree(PARENT, ctx());
86
- expect(children.length, why(SPEC, '§1.3 step 2 — one distinct sibling ref ⇒ one co-registered child')).toBe(1);
87
- expect(children[0]?.chainId, why(SPEC, 'child carries the composed chainId')).toBe('lesson-batch');
84
+ expect(children.length, req('openwop.it.chain-subchain-sibling.co-registers-the-referenced-sibling-as-its-own-workflow', SPEC, '§1.3 step 2 — one distinct sibling ref ⇒ one co-registered child')).toBe(1);
85
+ expect(children[0]?.chainId, req('openwop.it.chain-subchain-sibling.co-registers-the-referenced-sibling-as-its-own-workflow', SPEC, 'child carries the composed chainId')).toBe('lesson-batch');
88
86
  expect(
89
87
  children[0]?.fragment.nodes.length,
90
- why(SPEC, 'child is a fully expanded fragment (its own registered workflow)'),
88
+ req('openwop.it.chain-subchain-sibling.co-registers-the-referenced-sibling-as-its-own-workflow', SPEC, 'child is a fully expanded fragment (its own registered workflow)'),
91
89
  ).toBe(1);
92
90
  });
93
91
 
94
92
  it('mints a DETERMINISTIC, TENANT-SCOPED, version-pinned child id', () => {
95
93
  const { children } = expandChainTree(PARENT, ctx());
96
94
  const expected = mintChildWorkflowId('tenant-a', 'lesson-batch', '1.0.0');
97
- expect(children[0]?.childWorkflowId, why(SPEC, '§1.3 step 2 — deterministic (tenantId, childChainId, version) id')).toBe(
95
+ expect(children[0]?.childWorkflowId, req('openwop.it.chain-subchain-sibling.mints-a-deterministic-tenant-scoped-version-pinned-child-id', SPEC, '§1.3 step 2 — deterministic (tenantId, childChainId, version) id')).toBe(
98
96
  expected,
99
97
  );
100
98
  // Re-instantiating in the same tenant converges on the same id.
101
99
  const again = expandChainTree(PARENT, ctx());
102
- expect(again.children[0]?.childWorkflowId, why(SPEC, 'repeat instantiation in-tenant converges')).toBe(expected);
100
+ expect(again.children[0]?.childWorkflowId, req('openwop.it.chain-subchain-sibling.mints-a-deterministic-tenant-scoped-version-pinned-child-id', SPEC, 'repeat instantiation in-tenant converges')).toBe(expected);
103
101
  });
104
102
 
105
103
  it('scopes the child id per TENANT — two tenants NEVER collide on the global registry (isolation)', () => {
106
104
  const a = expandChainTree(PARENT, ctx('tenant-a')).children[0]?.childWorkflowId;
107
105
  const b = expandChainTree(PARENT, ctx('tenant-b')).children[0]?.childWorkflowId;
108
- expect(a, why(SPEC, 'tenant-a mints an id')).toBeTruthy();
106
+ expect(a, req('openwop.it.chain-subchain-sibling.scopes-the-child-id-per-tenant-two-tenants-never-collide-on-the-global-registry', SPEC, 'tenant-a mints an id')).toBeTruthy();
109
107
  expect(
110
108
  a !== b,
111
- why(SPEC, '§1.3 SECURITY sub-chain-child-tenant-scoped — distinct tenants ⇒ distinct child ids, no cross-tenant collision'),
109
+ req('openwop.it.chain-subchain-sibling.scopes-the-child-id-per-tenant-two-tenants-never-collide-on-the-global-registry', SPEC, '§1.3 SECURITY sub-chain-child-tenant-scoped — distinct tenants ⇒ distinct child ids, no cross-tenant collision'),
112
110
  ).toBe(true);
113
111
  });
114
112
 
115
113
  it('registers a child referenced twice exactly ONCE (dedup by deterministic id)', () => {
116
114
  const { children } = expandChainTree(PARENT, ctx());
117
115
  const ids = children.map((c) => c.childWorkflowId);
118
- expect(new Set(ids).size, why(SPEC, '§1.3 step 2 — a shared child registers once')).toBe(ids.length);
119
- expect(ids.length, why(SPEC, 'both build-0 + build-1 collapse to one child')).toBe(1);
116
+ expect(new Set(ids).size, req('openwop.it.chain-subchain-sibling.registers-a-child-referenced-twice-exactly-once-dedup-by-deterministic-id', SPEC, '§1.3 step 2 — a shared child registers once')).toBe(ids.length);
117
+ expect(ids.length, req('openwop.it.chain-subchain-sibling.registers-a-child-referenced-twice-exactly-once-dedup-by-deterministic-id', SPEC, 'both build-0 + build-1 collapse to one child')).toBe(1);
120
118
  });
121
119
 
122
120
  it('rewrites config.subChainRef → the minted child config.workflowId', () => {
123
121
  const { parent } = expandChainTree(PARENT, ctx());
124
122
  const expected = mintChildWorkflowId('tenant-a', 'lesson-batch', '1.0.0');
125
123
  const dispatchNodes = parent.nodes.filter((n) => n.typeId === 'core.subWorkflow');
126
- expect(dispatchNodes.length, why(SPEC, 'both dispatch nodes present')).toBe(2);
124
+ expect(dispatchNodes.length, req('openwop.it.chain-subchain-sibling.rewrites-config-subchainref-the-minted-child-config-workflowid', SPEC, 'both dispatch nodes present')).toBe(2);
127
125
  for (const n of dispatchNodes) {
128
126
  const config = n.config as Record<string, unknown>;
129
- expect(config['workflowId'], why(SPEC, '§1.3 step 3 — subChainRef rewritten to minted child id')).toBe(expected);
127
+ expect(config['workflowId'], req('openwop.it.chain-subchain-sibling.rewrites-config-subchainref-the-minted-child-config-workflowid', SPEC, '§1.3 step 3 — subChainRef rewritten to minted child id')).toBe(expected);
130
128
  expect(
131
129
  'subChainRef' in config,
132
- why(SPEC, '§1.3 step 3 — transient subChainRef key dropped from the runtime config'),
130
+ req('openwop.it.chain-subchain-sibling.rewrites-config-subchainref-the-minted-child-config-workflowid', SPEC, '§1.3 step 3 — transient subChainRef key dropped from the runtime config'),
133
131
  ).toBe(false);
134
132
  }
135
133
  });
@@ -140,7 +138,7 @@ describe('chain-subchain-sibling: co-registration (RFC 0133 §1, server-free)',
140
138
  const referenced = parent.nodes
141
139
  .filter((n) => n.typeId === 'core.subWorkflow')
142
140
  .map((n) => (n.config as Record<string, unknown>)['workflowId']);
143
- expect(referenced.every((id) => id === childId), why(SPEC, 'parent HOLDS the co-registered child at runtime')).toBe(
141
+ expect(referenced.every((id) => id === childId), req('openwop.it.chain-subchain-sibling.preserves-the-child-reference-at-runtime-concrete-workflowid-unlike-inline-mode', SPEC, 'parent HOLDS the co-registered child at runtime')).toBe(
144
142
  true,
145
143
  );
146
144
  });
@@ -33,6 +33,8 @@ import { describe, it, expect } from 'vitest';
33
33
  import { driver } from '../lib/driver.js';
34
34
  import { behaviorGate } from '../lib/behavior-gate.js';
35
35
  import { readCapabilityFamily } from '../lib/discovery-capabilities.js';
36
+ import { req } from '../lib/requirement-ids.js';
37
+ import { softSkip } from '../lib/soft-skip.js';
36
38
 
37
39
  const PROFILE = 'openwop-channel-presence';
38
40
  const SUBJECT_REF = /^(user|agent):.+/;
@@ -47,37 +49,37 @@ describe('channel-presence-behavioral (RFC 0110 §Conformance)', () => {
47
49
 
48
50
  const conversationId = 'conf:channel-presence:c1';
49
51
  const res = await driver.post('/v1/host/sample/channel-presence/snapshot', { conversationId, member: 'user:conformance-runner' });
50
- if (res.status === 404 || res.status === 405) return; // seam unwired — host witnesses via its own route test (dual-staging)
52
+ if (res.status === 404 || res.status === 405) return softSkip('blocked', 'precondition not met — `res.status === 404 || res.status === 405` returned early (seam unwired — host witnesses via its own route test (dual-staging)) (seam, prior step, or fixture unavailable)'); // seam unwired — host witnesses via its own route test (dual-staging)
51
53
 
52
54
  expect(
53
55
  res.status === 200,
54
- driver.describe('RFC 0110 §Proposal', 'the presence snapshot seam MUST return 200 for a member'),
56
+ req('openwop.it.channel-presence-behavioral.a-presence-snapshot-is-the-closed-members-only-non-vacuous-channel-presence-shap', 'RFC 0110 §Proposal', 'the presence snapshot seam MUST return 200 for a member'),
55
57
  ).toBe(true);
56
58
  const snap = res.json as PresenceSnapshot;
57
59
 
58
60
  // MUST 1 — CLOSED shape: exactly conversationId / present / typing (no PII field rides).
59
61
  expect(
60
62
  Object.keys(snap).sort().join(','),
61
- driver.describe('RFC 0110 §Proposal', 'channel.presence carries ONLY conversationId/present/typing (no PII)'),
63
+ req('openwop.it.channel-presence-behavioral.a-presence-snapshot-is-the-closed-members-only-non-vacuous-channel-presence-shap', 'RFC 0110 §Proposal', 'channel.presence carries ONLY conversationId/present/typing (no PII)'),
62
64
  ).toBe('conversationId,present,typing');
63
- expect(snap.conversationId, driver.describe('RFC 0110 §Proposal', 'the snapshot echoes the conversationId')).toBe(conversationId);
65
+ expect(snap.conversationId, req('openwop.it.channel-presence-behavioral.a-presence-snapshot-is-the-closed-members-only-non-vacuous-channel-presence-shap', 'RFC 0110 §Proposal', 'the snapshot echoes the conversationId')).toBe(conversationId);
64
66
 
65
67
  // MUST 2 — every ref is an opaque RFC 0041 subject ref (no PII).
66
68
  for (const ref of [...snap.present, ...snap.typing]) {
67
69
  expect(
68
70
  SUBJECT_REF.test(ref),
69
- driver.describe('RFC 0110 §Proposal / RFC 0041', `present/typing ref "${ref}" MUST be an opaque user:/agent: subject ref`),
71
+ req('openwop.it.channel-presence-behavioral.a-presence-snapshot-is-the-closed-members-only-non-vacuous-channel-presence-shap', 'RFC 0110 §Proposal / RFC 0041', `present/typing ref "${ref}" MUST be an opaque user:/agent: subject ref`),
70
72
  ).toBe(true);
71
73
  }
72
74
  // typing is a subset of present.
73
75
  for (const ref of snap.typing) {
74
- expect(snap.present.includes(ref), driver.describe('RFC 0110 §Proposal', 'every typing ref MUST also be present')).toBe(true);
76
+ expect(snap.present.includes(ref), req('openwop.it.channel-presence-behavioral.a-presence-snapshot-is-the-closed-members-only-non-vacuous-channel-presence-shap', 'RFC 0110 §Proposal', 'every typing ref MUST also be present')).toBe(true);
75
77
  }
76
78
 
77
79
  // MUST 3 — NON-VACUOUS: the snapshotting member is present.
78
80
  expect(
79
81
  snap.present.includes('user:conformance-runner'),
80
- driver.describe('RFC 0110 §Proposal', 'the snapshotting member MUST appear in present (members-only, real)'),
82
+ req('openwop.it.channel-presence-behavioral.a-presence-snapshot-is-the-closed-members-only-non-vacuous-channel-presence-shap', 'RFC 0110 §Proposal', 'the snapshotting member MUST appear in present (members-only, real)'),
81
83
  ).toBe(true);
82
84
  });
83
85
  });
@@ -34,8 +34,7 @@ import { join } from 'node:path';
34
34
  import Ajv2020 from 'ajv/dist/2020.js';
35
35
  import addFormats from 'ajv-formats';
36
36
  import { SCHEMAS_DIR } from '../lib/paths.js';
37
-
38
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
37
+ import { req } from '../lib/requirement-ids.js';
39
38
 
40
39
  function loadSchema(name: string): Record<string, unknown> {
41
40
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -49,26 +48,26 @@ describe('channel-presence-shape: the channel.presence payload (RFC 0110 §Propo
49
48
  it('a conforming presence snapshot (present + typing) validates', () => {
50
49
  expect(
51
50
  presence({ conversationId: 'chan-eng', present: ['user:alice', 'agent:iris'], typing: ['user:alice'] }),
52
- why('RFC 0110 §Proposal', 'a conforming channel.presence payload MUST validate'),
51
+ req('openwop.it.channel-presence-shape.a-conforming-presence-snapshot-present-typing-validates', 'RFC 0110 §Proposal', 'a conforming channel.presence payload MUST validate'),
53
52
  ).toBe(true);
54
53
  });
55
54
 
56
55
  it('typing is OPTIONAL — a snapshot with nobody typing validates', () => {
57
56
  expect(
58
57
  presence({ conversationId: 'chan-eng', present: ['user:alice'] }),
59
- why('RFC 0110 §Proposal', 'typing is optional'),
58
+ req('openwop.it.channel-presence-shape.typing-is-optional-a-snapshot-with-nobody-typing-validates', 'RFC 0110 §Proposal', 'typing is optional'),
60
59
  ).toBe(true);
61
60
  });
62
61
 
63
62
  it('conversationId and present are REQUIRED', () => {
64
- expect(presence({ present: ['user:a'] }), why('RFC 0110 §Proposal', 'conversationId is required')).toBe(false);
65
- expect(presence({ conversationId: 'c' }), why('RFC 0110 §Proposal', 'present is required')).toBe(false);
63
+ expect(presence({ present: ['user:a'] }), req('openwop.it.channel-presence-shape.conversationid-and-present-are-required', 'RFC 0110 §Proposal', 'conversationId is required')).toBe(false);
64
+ expect(presence({ conversationId: 'c' }), req('openwop.it.channel-presence-shape.conversationid-and-present-are-required', 'RFC 0110 §Proposal', 'present is required')).toBe(false);
66
65
  });
67
66
 
68
67
  it('the payload is CLOSED — a non-subject-ref field (ip/location) MUST be rejected (the no-PII guard)', () => {
69
68
  expect(
70
69
  presence({ conversationId: 'c', present: ['user:a'], ip: '10.0.0.1' }),
71
- why('RFC 0110 §Proposal', 'channel.presence MUST forbid extra keys — no PII rides the payload'),
70
+ req('openwop.it.channel-presence-shape.the-payload-is-closed-a-non-subject-ref-field-ip-location-must-be-rejected-the-n', 'RFC 0110 §Proposal', 'channel.presence MUST forbid extra keys — no PII rides the payload'),
72
71
  ).toBe(false);
73
72
  });
74
73
  });
@@ -77,7 +76,7 @@ describe('channel-presence-shape: event type + capability advertisement (RFC 011
77
76
  it('run-event.schema.json enumerates `channel.presence` as a RunEvent type', () => {
78
77
  const re = loadSchema('run-event.schema.json');
79
78
  const enumVals = JSON.stringify(re);
80
- expect(enumVals.includes('"channel.presence"'), why('RFC 0110 §Proposal', 'channel.presence MUST be a declared RunEvent type')).toBe(true);
79
+ expect(enumVals.includes('"channel.presence"'), req('openwop.it.channel-presence-shape.run-event-schema-json-enumerates-channel-presence-as-a-runevent-type', 'RFC 0110 §Proposal', 'channel.presence MUST be a declared RunEvent type')).toBe(true);
81
80
  });
82
81
 
83
82
  it('capabilities.schema.json declares channelPresence with supported, closed', () => {
@@ -85,9 +84,9 @@ describe('channel-presence-shape: event type + capability advertisement (RFC 011
85
84
  const block = (caps.properties as Record<string, Record<string, unknown>>).channelPresence as
86
85
  | { properties?: Record<string, unknown>; required?: string[]; additionalProperties?: boolean }
87
86
  | undefined;
88
- expect(block, why('RFC 0110 §Conformance', 'capabilities.channelPresence MUST be declared')).toBeDefined();
89
- expect(block?.properties?.supported, why('RFC 0110 §Conformance', 'channelPresence.supported MUST be declared')).toBeDefined();
90
- expect(block?.required, why('RFC 0110 §Conformance', 'supported MUST be required on the block')).toContain('supported');
91
- expect(block?.additionalProperties, why('RFC 0110 §Conformance', 'the block MUST be closed')).toBe(false);
87
+ expect(block, req('openwop.it.channel-presence-shape.capabilities-schema-json-declares-channelpresence-with-supported-closed', 'RFC 0110 §Conformance', 'capabilities.channelPresence MUST be declared')).toBeDefined();
88
+ expect(block?.properties?.supported, req('openwop.it.channel-presence-shape.capabilities-schema-json-declares-channelpresence-with-supported-closed', 'RFC 0110 §Conformance', 'channelPresence.supported MUST be declared')).toBeDefined();
89
+ expect(block?.required, req('openwop.it.channel-presence-shape.capabilities-schema-json-declares-channelpresence-with-supported-closed', 'RFC 0110 §Conformance', 'supported MUST be required on the block')).toContain('supported');
90
+ expect(block?.additionalProperties, req('openwop.it.channel-presence-shape.capabilities-schema-json-declares-channelpresence-with-supported-closed', 'RFC 0110 §Conformance', 'the block MUST be closed')).toBe(false);
92
91
  });
93
92
  });
@@ -22,6 +22,7 @@ import { describe, it, expect } from 'vitest';
22
22
  import { driver } from '../lib/driver.js';
23
23
  import { pollUntilTerminal } from '../lib/polling.js';
24
24
  import { isFixtureAdvertised } from '../lib/fixtures.js';
25
+ import { req } from '../lib/requirement-ids.js';
25
26
 
26
27
  const WORKFLOW_ID = 'conformance-channel-ttl';
27
28
  const SKIP_NO_FIXTURE = !isFixtureAdvertised(WORKFLOW_ID);
@@ -38,7 +39,7 @@ describe.skipIf(SKIP_NO_FIXTURE)('channel-ttl: conformance-channel-ttl drops ent
38
39
  const runId = (create.json as { runId: string }).runId;
39
40
 
40
41
  const terminal = await pollUntilTerminal(runId);
41
- expect(terminal.status, driver.describe(
42
+ expect(terminal.status, req('openwop.it.channel-ttl.after-the-post-ttl-write-the-channel-contains-exactly-one-entry-with-value-d',
42
43
  'fixtures.md conformance-channel-ttl §Terminal status',
43
44
  'fixture MUST reach terminal `completed`',
44
45
  )).toBe('completed');
@@ -46,22 +47,22 @@ describe.skipIf(SKIP_NO_FIXTURE)('channel-ttl: conformance-channel-ttl drops ent
46
47
  const variables = terminal.variables ?? {};
47
48
  const events = variables.events as ChannelEntry[] | undefined;
48
49
 
49
- expect(Array.isArray(events), driver.describe(
50
+ expect(Array.isArray(events), req('openwop.it.channel-ttl.after-the-post-ttl-write-the-channel-contains-exactly-one-entry-with-value-d',
50
51
  'channels-and-reducers.md §append',
51
52
  'channel state MUST be stored as an array of {value, _ts} entries',
52
53
  )).toBe(true);
53
54
 
54
- expect(events!.length, driver.describe(
55
+ expect(events!.length, req('openwop.it.channel-ttl.after-the-post-ttl-write-the-channel-contains-exactly-one-entry-with-value-d',
55
56
  'channels-and-reducers.md §TTL — write-time filter',
56
57
  'after the post-TTL write, exactly 1 entry MUST remain (the 3 priors aged out)',
57
58
  )).toBe(1);
58
59
 
59
- expect(events![0].value, driver.describe(
60
+ expect(events![0].value, req('openwop.it.channel-ttl.after-the-post-ttl-write-the-channel-contains-exactly-one-entry-with-value-d',
60
61
  'fixtures.md conformance-channel-ttl §Topology',
61
62
  'the surviving entry MUST be the post-delay write (value "d")',
62
63
  )).toBe('d');
63
64
 
64
- expect(typeof events![0]._ts, driver.describe(
65
+ expect(typeof events![0]._ts, req('openwop.it.channel-ttl.after-the-post-ttl-write-the-channel-contains-exactly-one-entry-with-value-d',
65
66
  'channels-and-reducers.md §append entry shape',
66
67
  'each channel entry MUST carry a numeric `_ts` write timestamp',
67
68
  )).toBe('number');
@@ -27,9 +27,9 @@
27
27
  */
28
28
 
29
29
  import { describe, it, expect } from 'vitest';
30
- import { driver } from '../lib/driver.js';
31
30
  import { behaviorGate, behaviorGatePresent } from '../lib/behavior-gate.js';
32
31
  import { readCardPacksCap, cardPacksSupported, executeCard } from '../lib/cardPacks.js';
32
+ import { req } from '../lib/requirement-ids.js';
33
33
 
34
34
  const PROFILE = 'openwop-chat-card-packs';
35
35
 
@@ -40,13 +40,13 @@ describe('chat-card-pack-execution: prompt -> envelope -> typed artifact (RFC 00
40
40
  if (!behaviorGatePresent(PROFILE, res)) return; // seam absent: skip default, FAIL strict
41
41
  expect(
42
42
  res.json['validated'],
43
- driver.describe('chat-card-packs.md "Card execution"', 'the host MUST validate the LLM output against the linked outputArtifactType schema'),
43
+ req('openwop.it.chat-card-pack-execution.a-registered-card-produces-a-schema-validated-artifact', 'chat-card-packs.md "Card execution"', 'the host MUST validate the LLM output against the linked outputArtifactType schema'),
44
44
  ).toBe(true);
45
45
  const evt = res.json['artifactCreated'] as { registered?: unknown } | undefined;
46
46
  if (evt && 'registered' in evt) {
47
47
  expect(
48
48
  evt.registered,
49
- driver.describe('run-event-payloads.schema.json artifactCreated', 'a validated card output MUST emit artifact.created with registered:true'),
49
+ req('openwop.it.chat-card-pack-execution.a-registered-card-produces-a-schema-validated-artifact', 'run-event-payloads.schema.json artifactCreated', 'a validated card output MUST emit artifact.created with registered:true'),
50
50
  ).toBe(true);
51
51
  }
52
52
  });
@@ -62,7 +62,7 @@ describe('chat-card-pack-execution: prompt -> envelope -> typed artifact (RFC 00
62
62
  if (!behaviorGatePresent(PROFILE, res.json['contentTrust'])) return; // FAIL strict
63
63
  expect(
64
64
  res.json['contentTrust'],
65
- driver.describe('chat-card-packs.md "Trust boundary" (R2)', 'a prompt segment derived from a card input MUST carry contentTrust:"untrusted"'),
65
+ req('openwop.it.chat-card-pack-execution.card-input-derived-prompt-content-propagates-contenttrust-untrusted-r2', 'chat-card-packs.md "Trust boundary" (R2)', 'a prompt segment derived from a card input MUST carry contentTrust:"untrusted"'),
66
66
  ).toBe('untrusted');
67
67
  });
68
68
  });
@@ -30,6 +30,7 @@ import Ajv2020 from 'ajv/dist/2020.js';
30
30
  import addFormats from 'ajv-formats';
31
31
  import type { ErrorObject } from 'ajv';
32
32
  import { SCHEMAS_DIR } from '../lib/paths.js';
33
+ import { req } from '../lib/requirement-ids.js';
33
34
 
34
35
  const SCHEMA_PATH = join(SCHEMAS_DIR, 'chat-card-pack-manifest.schema.json');
35
36
 
@@ -68,7 +69,7 @@ describe('category: chat-card-pack manifest validation', () => {
68
69
  it('positive: a valid chat card pack manifest validates cleanly', () => {
69
70
  expect(
70
71
  validate(validManifest()),
71
- `chat-card-packs.md §"Manifest format": a well-formed kind:"card" manifest MUST validate. Errors: ${JSON.stringify(validate.errors)}`,
72
+ req('openwop.it.chat-card-pack-manifest-validation.positive-a-valid-chat-card-pack-manifest-validates-cleanly', 'chat-card-packs.md', `chat-card-packs.md §"Manifest format": a well-formed kind:"card" manifest MUST validate. Errors: ${JSON.stringify(validate.errors)}`),
72
73
  ).toBe(true);
73
74
  });
74
75
 
@@ -77,24 +78,24 @@ describe('category: chat-card-pack manifest validation', () => {
77
78
  const errs = failsWith(manifest, 'additionalProperties');
78
79
  expect(
79
80
  errs.some((e) => (e.params as { additionalProperty?: string }).additionalProperty === 'artifactTypes'),
80
- 'chat-card-packs.md §"Pack kind": one kind per pack (additionalProperties:false)',
81
+ req('openwop.it.chat-card-pack-manifest-validation.negative-a-manifest-mixing-cards-and-artifacttypes-is-rejected', 'chat-card-packs.md', 'chat-card-packs.md §"Pack kind": one kind per pack (additionalProperties:false)'),
81
82
  ).toBe(true);
82
83
  });
83
84
 
84
85
  it('negative: an empty cards[] is rejected', () => {
85
- expect(failsWith({ ...validManifest(), cards: [] }, 'minItems').length).toBeGreaterThan(0);
86
+ expect(failsWith({ ...validManifest(), cards: [] }, 'minItems').length, req('openwop.it.chat-card-pack-manifest-validation.negative-an-empty-cards-is-rejected', 'chat-card-packs.md', 'negative: an empty cards[] is rejected')).toBeGreaterThan(0);
86
87
  });
87
88
 
88
89
  it('negative: an uppercase-scope cardTypeId is rejected', () => {
89
90
  const m = validManifest();
90
91
  m.cards[0]!.cardTypeId = 'Vendor.Acme.Card';
91
- expect(failsWith(m, 'pattern').length).toBeGreaterThan(0);
92
+ expect(failsWith(m, 'pattern').length, req('openwop.it.chat-card-pack-manifest-validation.negative-an-uppercase-scope-cardtypeid-is-rejected', 'chat-card-packs.md', 'negative: an uppercase-scope cardTypeId is rejected')).toBeGreaterThan(0);
92
93
  });
93
94
 
94
95
  it('negative: a card missing prompt is rejected', () => {
95
96
  const m = validManifest();
96
97
  delete (m.cards[0] as { prompt?: unknown }).prompt;
97
- expect(failsWith(m, 'required').length).toBeGreaterThan(0);
98
+ expect(failsWith(m, 'required').length, req('openwop.it.chat-card-pack-manifest-validation.negative-a-card-missing-prompt-is-rejected', 'chat-card-packs.md', 'negative: a card missing prompt is rejected')).toBeGreaterThan(0);
98
99
  });
99
100
 
100
101
  it('negative: a non-portable inputs[].type (canvas-reference) is rejected', () => {
@@ -102,7 +103,7 @@ describe('category: chat-card-pack manifest validation', () => {
102
103
  m.cards[0]!.inputs[0]!.type = 'canvas-reference';
103
104
  expect(
104
105
  failsWith(m, 'pattern').length,
105
- 'chat-card-packs.md §"Input fields": type is the closed portable enum OR a vendor.*/x- extension',
106
+ req('openwop.it.chat-card-pack-manifest-validation.negative-a-non-portable-inputs-type-canvas-reference-is-rejected', 'chat-card-packs.md', 'chat-card-packs.md §"Input fields": type is the closed portable enum OR a vendor.*/x- extension'),
106
107
  ).toBeGreaterThan(0);
107
108
  });
108
109
 
@@ -111,7 +112,7 @@ describe('category: chat-card-pack manifest validation', () => {
111
112
  m.cards[0]!.inputs[0]!.type = 'vendor.myndhyve.canvas-ref';
112
113
  expect(
113
114
  validate(m),
114
- 'chat-card-packs.md §"Input fields": a vendor.<org>.<kind> input type extension MUST validate (other hosts ignore it)',
115
+ req('openwop.it.chat-card-pack-manifest-validation.positive-a-vendor-prefixed-inputs-type-extension-is-tolerated', 'chat-card-packs.md', 'chat-card-packs.md §"Input fields": a vendor.<org>.<kind> input type extension MUST validate (other hosts ignore it)'),
115
116
  ).toBe(true);
116
117
  });
117
118
 
@@ -121,7 +122,7 @@ describe('category: chat-card-pack manifest validation', () => {
121
122
  m.cards[0]!.inputs[0]!.type = t;
122
123
  expect(
123
124
  validate(m),
124
- `chat-card-packs.md §"Input fields": portable inputs[].type "${t}" MUST validate (G9 resolved 2026-05-27)`,
125
+ req('openwop.it.chat-card-pack-manifest-validation.positive-the-full-portable-inputs-type-subset-validates-g9-incl-multiselect-file', 'chat-card-packs.md', `chat-card-packs.md §"Input fields": portable inputs[].type "${t}" MUST validate (G9 resolved 2026-05-27)`),
125
126
  ).toBe(true);
126
127
  }
127
128
  });
@@ -20,6 +20,7 @@
20
20
  import { describe, it, expect } from 'vitest';
21
21
  import { softSkip } from '../lib/soft-skip.js';
22
22
  import { driver } from '../lib/driver.js';
23
+ import { req } from '../lib/requirement-ids.js';
23
24
 
24
25
  interface CommitmentCaps {
25
26
  agents?: { commitments?: { supported?: boolean } };
@@ -54,14 +55,14 @@ describe('commitment-fired: fire contract (RFC 0068 §C, capability-gated)', ()
54
55
  });
55
56
  if (res.status === 404 || res.status === 501) return softSkip('blocked', 'seam not wired — soft-skip');
56
57
 
57
- expect(res.status, driver.describe('RFC 0068 §C', 'an advertised commitment seam MUST succeed')).toBe(200);
58
+ expect(res.status, req('openwop.it.commitment-fired.a-fired-commitment-emits-a-content-free-event-with-memory-provenance-exactly-onc', 'RFC 0068 §C', 'an advertised commitment seam MUST succeed')).toBe(200);
58
59
  const r = res.json as FireResult;
59
60
 
60
61
  // §C — required identifiers.
61
- expect(r.event?.commitmentId, driver.describe('RFC 0068 §C', 'commitment.fired MUST carry commitmentId')).toBeTruthy();
62
+ expect(r.event?.commitmentId, req('openwop.it.commitment-fired.a-fired-commitment-emits-a-content-free-event-with-memory-provenance-exactly-onc', 'RFC 0068 §C', 'commitment.fired MUST carry commitmentId')).toBeTruthy();
62
63
  expect(
63
64
  r.event?.memoryRef,
64
- driver.describe('RFC 0068 §C.1', 'commitment.fired MUST carry the source memoryRef (CTI-1 provenance)'),
65
+ req('openwop.it.commitment-fired.a-fired-commitment-emits-a-content-free-event-with-memory-provenance-exactly-onc', 'RFC 0068 §C.1', 'commitment.fired MUST carry the source memoryRef (CTI-1 provenance)'),
65
66
  ).toBeTruthy();
66
67
 
67
68
  // §C.3 — content-free: the inferred intention text MUST NOT appear on the event.
@@ -69,7 +70,7 @@ describe('commitment-fired: fire contract (RFC 0068 §C, capability-gated)', ()
69
70
  const serialized = JSON.stringify(r.event ?? {});
70
71
  expect(
71
72
  serialized.includes(r.intentionCanary),
72
- driver.describe('RFC 0068 §C.3', 'the inferred intention text MUST NOT appear on the commitment.fired payload'),
73
+ req('openwop.it.commitment-fired.a-fired-commitment-emits-a-content-free-event-with-memory-provenance-exactly-onc', 'RFC 0068 §C.3', 'the inferred intention text MUST NOT appear on the commitment.fired payload'),
73
74
  ).toBe(false);
74
75
  }
75
76
 
@@ -77,7 +78,7 @@ describe('commitment-fired: fire contract (RFC 0068 §C, capability-gated)', ()
77
78
  if (typeof r.fireCount === 'number') {
78
79
  expect(
79
80
  r.fireCount,
80
- driver.describe('RFC 0068 §C.2', 'a commitment MUST fire at most once per satisfied condition'),
81
+ req('openwop.it.commitment-fired.a-fired-commitment-emits-a-content-free-event-with-memory-provenance-exactly-onc', 'RFC 0068 §C.2', 'a commitment MUST fire at most once per satisfied condition'),
81
82
  ).toBeLessThanOrEqual(1);
82
83
  }
83
84
  });