@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
@@ -38,9 +38,7 @@ import { join } from 'node:path';
38
38
  import Ajv2020 from 'ajv/dist/2020.js';
39
39
  import addFormats from 'ajv-formats';
40
40
  import { SCHEMAS_DIR } from '../lib/paths.js';
41
-
42
- /** Server-free assertion-message helper. */
43
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
41
+ import { req } from '../lib/requirement-ids.js';
44
42
 
45
43
  function loadSchema(name: string): Record<string, unknown> {
46
44
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -51,11 +49,11 @@ describe('agent-deployment-shape: capability advertisement (RFC 0082, server-fre
51
49
  const caps = loadSchema('capabilities.schema.json');
52
50
  const agents = (caps.properties as Record<string, { properties?: Record<string, { properties?: Record<string, unknown> }> }>).agents;
53
51
  const deployment = agents?.properties?.deployment;
54
- expect(deployment, why('capabilities.md §agents', 'agents.deployment MUST be declared')).toBeDefined();
52
+ expect(deployment, req('openwop.it.agent-deployment-shape.the-capabilities-schema-declares-agents-deployment-with-its-sub-flags', 'capabilities.md §agents', 'agents.deployment MUST be declared')).toBeDefined();
55
53
  for (const flag of ['supported', 'channels', 'canary', 'rollback', 'states']) {
56
54
  expect(
57
55
  deployment?.properties?.[flag],
58
- why('agent-deployment.md §F', `agents.deployment.${flag} MUST be declared`),
56
+ req('openwop.it.agent-deployment-shape.the-capabilities-schema-declares-agents-deployment-with-its-sub-flags', 'agent-deployment.md §F', `agents.deployment.${flag} MUST be declared`),
59
57
  ).toBeDefined();
60
58
  }
61
59
  });
@@ -69,16 +67,16 @@ describe('agent-deployment-shape: deployment record + AgentRef binding (RFC 0082
69
67
 
70
68
  it('AgentDeployment validates a conforming record and rejects a bad state / out-of-range canary', () => {
71
69
  const good = { agentId: 'core.openwop.agents.support-resolver', version: '2.4.0', state: 'active', canaryPercent: 10, channels: ['stable'] };
72
- expect(record(good), why('RFC 0082 §C', 'a conforming deployment record MUST validate')).toBe(true);
73
- expect(record({ ...good, state: 'live' }), why('RFC 0082 §C', 'an out-of-enum state MUST be rejected')).toBe(false);
74
- expect(record({ ...good, canaryPercent: 150 }), why('RFC 0082 §C', 'canaryPercent > 100 MUST be rejected')).toBe(false);
70
+ expect(record(good), req('openwop.it.agent-deployment-shape.agentdeployment-validates-a-conforming-record-and-rejects-a-bad-state-out-of-ran', 'RFC 0082 §C', 'a conforming deployment record MUST validate')).toBe(true);
71
+ expect(record({ ...good, state: 'live' }), req('openwop.it.agent-deployment-shape.agentdeployment-validates-a-conforming-record-and-rejects-a-bad-state-out-of-ran', 'RFC 0082 §C', 'an out-of-enum state MUST be rejected')).toBe(false);
72
+ expect(record({ ...good, canaryPercent: 150 }), req('openwop.it.agent-deployment-shape.agentdeployment-validates-a-conforming-record-and-rejects-a-bad-state-out-of-ran', 'RFC 0082 §C', 'canaryPercent > 100 MUST be rejected')).toBe(false);
75
73
  });
76
74
 
77
75
  it('AgentRef channel XOR version: each alone and neither validate; both is rejected (RFC 0082 §A)', () => {
78
- expect(agentRef({ agentId: 'core.x.y.z', version: '1.0.0' }), why('RFC 0082 §A', 'version-only AgentRef MUST validate')).toBe(true);
79
- expect(agentRef({ agentId: 'core.x.y.z', channel: 'stable' }), why('RFC 0082 §A', 'channel-only AgentRef MUST validate')).toBe(true);
80
- expect(agentRef({ agentId: 'core.x.y.z' }), why('RFC 0082 §A', 'a ref with neither version nor channel MUST validate (host default)')).toBe(true);
81
- expect(agentRef({ agentId: 'core.x.y.z', version: '1.0.0', channel: 'stable' }), why('RFC 0082 §A', 'a ref with BOTH version and channel MUST be rejected')).toBe(false);
76
+ expect(agentRef({ agentId: 'core.x.y.z', version: '1.0.0' }), req('openwop.it.agent-deployment-shape.agentref-channel-xor-version-each-alone-and-neither-validate-both-is-rejected-rf', 'RFC 0082 §A', 'version-only AgentRef MUST validate')).toBe(true);
77
+ expect(agentRef({ agentId: 'core.x.y.z', channel: 'stable' }), req('openwop.it.agent-deployment-shape.agentref-channel-xor-version-each-alone-and-neither-validate-both-is-rejected-rf', 'RFC 0082 §A', 'channel-only AgentRef MUST validate')).toBe(true);
78
+ expect(agentRef({ agentId: 'core.x.y.z' }), req('openwop.it.agent-deployment-shape.agentref-channel-xor-version-each-alone-and-neither-validate-both-is-rejected-rf', 'RFC 0082 §A', 'a ref with neither version nor channel MUST validate (host default)')).toBe(true);
79
+ expect(agentRef({ agentId: 'core.x.y.z', version: '1.0.0', channel: 'stable' }), req('openwop.it.agent-deployment-shape.agentref-channel-xor-version-each-alone-and-neither-validate-both-is-rejected-rf', 'RFC 0082 §A', 'a ref with BOTH version and channel MUST be rejected')).toBe(false);
82
80
  });
83
81
  });
84
82
 
@@ -94,29 +92,29 @@ describe('agent-deployment-shape: deployment.* event payloads (RFC 0082, server-
94
92
  const stateChanged = ajv.getSchema('payloads#/$defs/deploymentStateChanged');
95
93
 
96
94
  it('deployment.promoted validates a content-free promotion record and requires toVersion + toState', () => {
97
- expect(promoted, 'the deploymentPromoted $def MUST exist').toBeTruthy();
95
+ expect(promoted, req('openwop.it.agent-deployment-shape.deployment-promoted-validates-a-content-free-promotion-record-and-requires-tover', 'RFC 0082', 'the deploymentPromoted $def MUST exist')).toBeTruthy();
98
96
  expect(
99
97
  promoted!({ agentId: 'core.openwop.agents.support-resolver', toVersion: '2.4.0', toState: 'active', channel: 'stable', canaryPercent: 10, evalRunId: 'run_abc' }),
100
- why('RFC 0082 §D', 'a conforming deployment.promoted payload MUST validate'),
98
+ req('openwop.it.agent-deployment-shape.deployment-promoted-validates-a-content-free-promotion-record-and-requires-tover', 'RFC 0082 §D', 'a conforming deployment.promoted payload MUST validate'),
101
99
  ).toBe(true);
102
- expect(promoted!({ agentId: 'a' }), why('RFC 0082 §D', 'deployment.promoted without toVersion/toState MUST be rejected')).toBe(false);
100
+ expect(promoted!({ agentId: 'a' }), req('openwop.it.agent-deployment-shape.deployment-promoted-validates-a-content-free-promotion-record-and-requires-tover', 'RFC 0082 §D', 'deployment.promoted without toVersion/toState MUST be rejected')).toBe(false);
103
101
  });
104
102
 
105
103
  it('deployment.rolled-back / canary.adjusted / state.changed validate conforming records', () => {
106
- expect(rolledBack!({ agentId: 'a', fromVersion: '2.4.0', toVersion: '2.3.1', rollbackPointer: '2.3.1' }), why('RFC 0082 §D', 'a conforming deployment.rolled-back MUST validate')).toBe(true);
107
- expect(canary!({ agentId: 'a', version: '2.4.0', fromPercent: 10, toPercent: 50 }), why('RFC 0082 §D', 'a conforming deployment.canary.adjusted MUST validate')).toBe(true);
108
- expect(stateChanged!({ agentId: 'a', version: '2.4.0', fromState: 'active', toState: 'paused' }), why('RFC 0082 §D', 'a conforming deployment.state.changed MUST validate')).toBe(true);
109
- expect(stateChanged!({ agentId: 'a', version: '2.4.0', fromState: 'active', toState: 'live' }), why('RFC 0082 §D', 'an out-of-enum toState MUST be rejected')).toBe(false);
104
+ expect(rolledBack!({ agentId: 'a', fromVersion: '2.4.0', toVersion: '2.3.1', rollbackPointer: '2.3.1' }), req('openwop.it.agent-deployment-shape.deployment-rolled-back-canary-adjusted-state-changed-validate-conforming-records', 'RFC 0082 §D', 'a conforming deployment.rolled-back MUST validate')).toBe(true);
105
+ expect(canary!({ agentId: 'a', version: '2.4.0', fromPercent: 10, toPercent: 50 }), req('openwop.it.agent-deployment-shape.deployment-rolled-back-canary-adjusted-state-changed-validate-conforming-records', 'RFC 0082 §D', 'a conforming deployment.canary.adjusted MUST validate')).toBe(true);
106
+ expect(stateChanged!({ agentId: 'a', version: '2.4.0', fromState: 'active', toState: 'paused' }), req('openwop.it.agent-deployment-shape.deployment-rolled-back-canary-adjusted-state-changed-validate-conforming-records', 'RFC 0082 §D', 'a conforming deployment.state.changed MUST validate')).toBe(true);
107
+ expect(stateChanged!({ agentId: 'a', version: '2.4.0', fromState: 'active', toState: 'live' }), req('openwop.it.agent-deployment-shape.deployment-rolled-back-canary-adjusted-state-changed-validate-conforming-records', 'RFC 0082 §D', 'an out-of-enum toState MUST be rejected')).toBe(false);
110
108
  });
111
109
 
112
110
  it('deployment.* events are content-free — a manifest body and a prompt are rejected (deployment-event-no-content-leak)', () => {
113
111
  expect(
114
112
  promoted!({ agentId: 'a', toVersion: '2.4.0', toState: 'active', manifestBody: '{...}' }),
115
- why('SECURITY invariant deployment-event-no-content-leak', 'a deployment.promoted MUST NOT carry a manifest body'),
113
+ req('openwop.it.agent-deployment-shape.deployment-events-are-content-free-a-manifest-body-and-a-prompt-are-rejected-dep', 'SECURITY invariant deployment-event-no-content-leak', 'a deployment.promoted MUST NOT carry a manifest body'),
116
114
  ).toBe(false);
117
115
  expect(
118
116
  stateChanged!({ agentId: 'a', version: '2.4.0', fromState: 'active', toState: 'paused', prompt: 'system: …' }),
119
- why('SECURITY invariant deployment-event-no-content-leak', 'a deployment.state.changed MUST NOT carry prompt content'),
117
+ req('openwop.it.agent-deployment-shape.deployment-events-are-content-free-a-manifest-body-and-a-prompt-are-rejected-dep', 'SECURITY invariant deployment-event-no-content-leak', 'a deployment.state.changed MUST NOT carry prompt content'),
120
118
  ).toBe(false);
121
119
  });
122
120
  });
@@ -125,15 +123,15 @@ describe('agent-deployment-shape: §B recorded-fact pin + enum (RFC 0082, server
125
123
  it('agent.invocation.started carries the additive recorded-fact resolvedAgentVersion / resolvedChannel', () => {
126
124
  const payloads = loadSchema('run-event-payloads.schema.json');
127
125
  const started = ((payloads.$defs as Record<string, { properties?: Record<string, unknown> }>).agentInvocationStarted)?.properties ?? {};
128
- expect(started.resolvedAgentVersion, why('RFC 0082 §B', 'agent.invocation.started.resolvedAgentVersion MUST be declared (the channel pin)')).toBeDefined();
129
- expect(started.resolvedChannel, why('RFC 0082 §B', 'agent.invocation.started.resolvedChannel MUST be declared')).toBeDefined();
126
+ expect(started.resolvedAgentVersion, req('openwop.it.agent-deployment-shape.agent-invocation-started-carries-the-additive-recorded-fact-resolvedagentversion', 'RFC 0082 §B', 'agent.invocation.started.resolvedAgentVersion MUST be declared (the channel pin)')).toBeDefined();
127
+ expect(started.resolvedChannel, req('openwop.it.agent-deployment-shape.agent-invocation-started-carries-the-additive-recorded-fact-resolvedagentversion', 'RFC 0082 §B', 'agent.invocation.started.resolvedChannel MUST be declared')).toBeDefined();
130
128
  });
131
129
 
132
130
  it('all four deployment event names appear in the RunEventType enum', () => {
133
131
  const runEvent = loadSchema('run-event.schema.json');
134
132
  const enumVals = (runEvent.$defs as Record<string, { enum?: string[] }>).RunEventType?.enum ?? [];
135
133
  for (const e of ['deployment.promoted', 'deployment.rolled-back', 'deployment.canary.adjusted', 'deployment.state.changed']) {
136
- expect(enumVals).toContain(e);
134
+ expect(enumVals, req('openwop.it.agent-deployment-shape.all-four-deployment-event-names-appear-in-the-runeventtype-enum', 'RFC 0082', 'all four deployment event names appear in the RunEventType enum')).toContain(e);
137
135
  }
138
136
  });
139
137
  });
@@ -29,7 +29,6 @@ import { readFileSync } from 'node:fs';
29
29
  import { join } from 'node:path';
30
30
  import Ajv2020 from 'ajv/dist/2020.js';
31
31
  import addFormats from 'ajv-formats';
32
- import { driver } from '../lib/driver.js';
33
32
  import { behaviorGate } from '../lib/behavior-gate.js';
34
33
  import { SCHEMAS_DIR } from '../lib/paths.js';
35
34
  import {
@@ -39,6 +38,8 @@ import {
39
38
  EVAL_CONTENT_FORBIDDEN,
40
39
  } from '../lib/agentEval.js';
41
40
  import { queryTestEvents, requireEvents, isEventLogSeamAvailable, resetTestSeam } from '../lib/event-log-query.js';
41
+ import { req } from '../lib/requirement-ids.js';
42
+ import { softSkip } from '../lib/soft-skip.js';
42
43
 
43
44
  function loadSchema(name: string): Record<string, unknown> {
44
45
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -48,7 +49,7 @@ function expectContentFree(payload: Record<string, unknown>, where: string): voi
48
49
  for (const f of EVAL_CONTENT_FORBIDDEN) {
49
50
  expect(
50
51
  !(f in payload),
51
- driver.describe('RFC 0081 §C (eval-summary-no-content-leak)', `${where} MUST be content-free (no ${f})`),
52
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'RFC 0081 §C (eval-summary-no-content-leak)', `${where} MUST be content-free (no ${f})`),
52
53
  ).toBe(true);
53
54
  }
54
55
  }
@@ -57,10 +58,10 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
57
58
  it('emits eval.started → per-task eval.scored → eval.completed and serves a content-free EvalSummary', async () => {
58
59
  const cap = await readEvalSuiteCap();
59
60
  if (!behaviorGate('openwop-eval-run', cap?.supported === true)) return;
60
- if (!(await isEventLogSeamAvailable())) return; // event-log seam absent — soft-skip
61
+ if (!(await isEventLogSeamAvailable())) return softSkip('blocked', 'precondition not met — `!(await isEventLogSeamAvailable())` returned early (event-log seam absent — soft-skip) (seam, prior step, or fixture unavailable)'); // event-log seam absent — soft-skip
61
62
 
62
63
  const run = await driveEvalRun({ modes: ['golden'] });
63
- if (run === null) return; // eval-run seam unwired — soft-skip the whole behavioral suite
64
+ if (run === null) return softSkip('blocked', 'precondition not met — `run === null` returned early (eval-run seam unwired — soft-skip the whole behavioral suite) (seam, prior step, or fixture unavailable)'); // eval-run seam unwired — soft-skip the whole behavioral suite
64
65
 
65
66
  // From here the host has ADVERTISED agents.evalSuite AND wired the eval-run
66
67
  // seam — missing evidence is a FAILURE, not a soft-skip. A host claiming the
@@ -68,7 +69,7 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
68
69
  // normative EvalSummary, or it is advertising a capability it doesn't deliver.
69
70
  expect(
70
71
  typeof run.runId === 'string' && run.runId.length > 0,
71
- driver.describe('agent-evaluation.md §B', 'a wired eval-run seam MUST return the projected runId'),
72
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §B', 'a wired eval-run seam MUST return the projected runId'),
72
73
  ).toBe(true);
73
74
  const runId = run.runId as string;
74
75
 
@@ -87,15 +88,15 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
87
88
  // ≥1 eval.scored — a wired eval run MUST emit the full sequence.
88
89
  expect(
89
90
  startedEvents.length === 1,
90
- driver.describe('agent-evaluation.md §C', 'an eval run MUST emit exactly one eval.started'),
91
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', 'an eval run MUST emit exactly one eval.started'),
91
92
  ).toBe(true);
92
93
  expect(
93
94
  scoredEvents.length >= 1,
94
- driver.describe('agent-evaluation.md §C', 'an eval run MUST emit at least one eval.scored'),
95
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', 'an eval run MUST emit at least one eval.scored'),
95
96
  ).toBe(true);
96
97
  expect(
97
98
  completedEvents.length === 1,
98
- driver.describe('agent-evaluation.md §C', 'an eval run MUST emit exactly one eval.completed'),
99
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', 'an eval run MUST emit exactly one eval.completed'),
99
100
  ).toBe(true);
100
101
  const started = startedEvents[0]!;
101
102
  const completed = completedEvents[0]!;
@@ -104,22 +105,22 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
104
105
  for (const s of scoredEvents) {
105
106
  expect(
106
107
  started.sequence < s.sequence,
107
- driver.describe('agent-evaluation.md §C', 'eval.started MUST precede every eval.scored'),
108
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', 'eval.started MUST precede every eval.scored'),
108
109
  ).toBe(true);
109
110
  expect(
110
111
  s.sequence < completed.sequence,
111
- driver.describe('agent-evaluation.md §C', 'every eval.scored MUST precede eval.completed'),
112
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', 'every eval.scored MUST precede eval.completed'),
112
113
  ).toBe(true);
113
114
  }
114
115
 
115
116
  // One eval.scored per task (count == eval.completed.taskCount).
116
117
  expect(
117
118
  typeof completed.payload.taskCount === 'number',
118
- driver.describe('run-event-payloads.schema.json#/$defs/evalCompleted', 'eval.completed MUST carry a numeric taskCount'),
119
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'run-event-payloads.schema.json#/$defs/evalCompleted', 'eval.completed MUST carry a numeric taskCount'),
119
120
  ).toBe(true);
120
121
  expect(
121
122
  scoredEvents.length === completed.payload.taskCount,
122
- driver.describe('agent-evaluation.md §C', 'one eval.scored per task (count == eval.completed.taskCount)'),
123
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', 'one eval.scored per task (count == eval.completed.taskCount)'),
123
124
  ).toBe(true);
124
125
 
125
126
  // Content-free (§C / eval-summary-no-content-leak) + score ∈ 0..1, passed boolean.
@@ -129,11 +130,11 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
129
130
  expectContentFree(s.payload, 'eval.scored');
130
131
  expect(
131
132
  typeof s.payload.score === 'number' && (s.payload.score as number) >= 0 && (s.payload.score as number) <= 1,
132
- driver.describe('run-event-payloads.schema.json#/$defs/evalScored', 'eval.scored.score MUST be in 0..1'),
133
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'run-event-payloads.schema.json#/$defs/evalScored', 'eval.scored.score MUST be in 0..1'),
133
134
  ).toBe(true);
134
135
  expect(
135
136
  typeof s.payload.passed === 'boolean',
136
- driver.describe('run-event-payloads.schema.json#/$defs/evalScored', 'eval.scored.passed MUST be a boolean'),
137
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'run-event-payloads.schema.json#/$defs/evalScored', 'eval.scored.passed MUST be a boolean'),
137
138
  ).toBe(true);
138
139
  }
139
140
 
@@ -141,7 +142,7 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
141
142
  const { status, summary } = await getEvalSummary(runId);
142
143
  expect(
143
144
  status === 200 && summary !== undefined,
144
- driver.describe('agent-evaluation.md §C', `GET /v1/runs/{runId}/eval-summary MUST serve a 200 EvalSummary for a completed eval run (got ${status})`),
145
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', `GET /v1/runs/{runId}/eval-summary MUST serve a 200 EvalSummary for a completed eval run (got ${status})`),
145
146
  ).toBe(true);
146
147
  const sum = summary as Record<string, unknown>;
147
148
  const ajv = new Ajv2020({ strict: false, allErrors: true });
@@ -149,7 +150,7 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
149
150
  const validate = ajv.compile(loadSchema('eval-summary.schema.json'));
150
151
  expect(
151
152
  validate(sum),
152
- driver.describe('eval-summary.schema.json', `EvalSummary MUST be schema-valid (${ajv.errorsText(validate.errors)})`),
153
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'eval-summary.schema.json', `EvalSummary MUST be schema-valid (${ajv.errorsText(validate.errors)})`),
153
154
  ).toBe(true);
154
155
 
155
156
  const tasks = (sum.tasks as Array<Record<string, unknown>> | undefined) ?? [];
@@ -157,11 +158,11 @@ describe('agent-eval-run (RFC 0081 §B/§C)', () => {
157
158
  const taskCount = sum.taskCount as number | undefined;
158
159
  expect(
159
160
  typeof passedCount === 'number' && typeof taskCount === 'number',
160
- driver.describe('eval-summary.schema.json', 'EvalSummary MUST carry numeric passedCount + taskCount'),
161
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'eval-summary.schema.json', 'EvalSummary MUST carry numeric passedCount + taskCount'),
161
162
  ).toBe(true);
162
163
  expect(
163
164
  (passedCount as number) <= (taskCount as number),
164
- driver.describe('agent-evaluation.md §C', 'EvalSummary.passedCount MUST NOT exceed taskCount'),
165
+ req('openwop.it.agent-eval-run.emits-eval-started-per-task-eval-scored-eval-completed-and-serves-a-content-free', 'agent-evaluation.md §C', 'EvalSummary.passedCount MUST NOT exceed taskCount'),
165
166
  ).toBe(true);
166
167
  for (const t of tasks) {
167
168
  expectContentFree(t, 'EvalSummary.tasks[]');
@@ -33,9 +33,7 @@ import { join } from 'node:path';
33
33
  import Ajv2020 from 'ajv/dist/2020.js';
34
34
  import addFormats from 'ajv-formats';
35
35
  import { SCHEMAS_DIR } from '../lib/paths.js';
36
-
37
- /** Server-free assertion-message helper (mirrors driver.describe's "spec — requirement" shape without requiring OPENWOP_BASE_URL). */
38
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
36
+ import { req } from '../lib/requirement-ids.js';
39
37
 
40
38
  function loadSchema(name: string): Record<string, unknown> {
41
39
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -48,12 +46,12 @@ describe('agent-eval-suite-shape: capability advertisement (RFC 0081, server-fre
48
46
  const evalSuite = agents?.properties?.evalSuite;
49
47
  expect(
50
48
  evalSuite,
51
- why('capabilities.md §agents', 'agents.evalSuite MUST be declared'),
49
+ req('openwop.it.agent-eval-suite-shape.the-capabilities-schema-declares-agents-evalsuite-with-its-sub-flags', 'capabilities.md §agents', 'agents.evalSuite MUST be declared'),
52
50
  ).toBeDefined();
53
51
  for (const flag of ['supported', 'modes']) {
54
52
  expect(
55
53
  evalSuite?.properties?.[flag],
56
- why('agent-evaluation.md §Capability advertisement', `agents.evalSuite.${flag} MUST be declared`),
54
+ req('openwop.it.agent-eval-suite-shape.the-capabilities-schema-declares-agents-evalsuite-with-its-sub-flags', 'agent-evaluation.md §Capability advertisement', `agents.evalSuite.${flag} MUST be declared`),
57
55
  ).toBeDefined();
58
56
  }
59
57
  });
@@ -75,11 +73,11 @@ describe('agent-eval-suite-shape: AgentEvalSuite + EvalSummary schemas (RFC 0081
75
73
  { taskId: 'refund-window', input: { q: 'refund policy?' }, expected: { kind: 'golden', match: { strategy: 'contains', value: '30 days' } } },
76
74
  ],
77
75
  };
78
- expect(suite(good), why('RFC 0081 §A', 'a conforming AgentEvalSuite MUST validate')).toBe(true);
76
+ expect(suite(good), req('openwop.it.agent-eval-suite-shape.agentevalsuite-validates-a-conforming-suite-and-rejects-a-malformed-suiteid-out', 'RFC 0081 §A', 'a conforming AgentEvalSuite MUST validate')).toBe(true);
79
77
  // Negative: suiteId must carry the `.evals.` infix.
80
- expect(suite({ ...good, suiteId: 'core.openwop.support-resolver' }), why('RFC 0081 §A', 'a suiteId without the `.evals.` infix MUST be rejected')).toBe(false);
78
+ expect(suite({ ...good, suiteId: 'core.openwop.support-resolver' }), req('openwop.it.agent-eval-suite-shape.agentevalsuite-validates-a-conforming-suite-and-rejects-a-malformed-suiteid-out', 'RFC 0081 §A', 'a suiteId without the `.evals.` infix MUST be rejected')).toBe(false);
81
79
  // Negative: passScore out of 0..1.
82
- expect(suite({ ...good, thresholds: { passScore: 1.5 } }), why('RFC 0081 §A', 'thresholds.passScore > 1 MUST be rejected')).toBe(false);
80
+ expect(suite({ ...good, thresholds: { passScore: 1.5 } }), req('openwop.it.agent-eval-suite-shape.agentevalsuite-validates-a-conforming-suite-and-rejects-a-malformed-suiteid-out', 'RFC 0081 §A', 'thresholds.passScore > 1 MUST be rejected')).toBe(false);
83
81
  });
84
82
 
85
83
  it('EvalSummary validates a conforming scorecard and rejects an out-of-range score', () => {
@@ -92,8 +90,8 @@ describe('agent-eval-suite-shape: AgentEvalSuite + EvalSummary schemas (RFC 0081
92
90
  passedCount: 2,
93
91
  tasks: [{ taskId: 'refund-window', score: 0.9, passed: true, safetyFindings: [{ kind: 'jailbreak', severity: 'low' }] }],
94
92
  };
95
- expect(summary(good), why('RFC 0081 §C', 'a conforming EvalSummary MUST validate')).toBe(true);
96
- expect(summary({ ...good, aggregateScore: 1.4 }), why('RFC 0081 §C', 'aggregateScore > 1 MUST be rejected')).toBe(false);
93
+ expect(summary(good), req('openwop.it.agent-eval-suite-shape.evalsummary-validates-a-conforming-scorecard-and-rejects-an-out-of-range-score', 'RFC 0081 §C', 'a conforming EvalSummary MUST validate')).toBe(true);
94
+ expect(summary({ ...good, aggregateScore: 1.4 }), req('openwop.it.agent-eval-suite-shape.evalsummary-validates-a-conforming-scorecard-and-rejects-an-out-of-range-score', 'RFC 0081 §C', 'aggregateScore > 1 MUST be rejected')).toBe(false);
97
95
  });
98
96
 
99
97
  it('EvalSummary is content-free — a task-output body and a safety-finding excerpt are rejected (eval-summary-no-content-leak)', () => {
@@ -101,12 +99,12 @@ describe('agent-eval-suite-shape: AgentEvalSuite + EvalSummary schemas (RFC 0081
101
99
  // Negative: a per-task entry carrying the output body.
102
100
  expect(
103
101
  summary({ ...base, tasks: [{ taskId: 't1', score: 0.5, passed: false, taskOutput: 'the model said …' }] }),
104
- why('SECURITY invariant eval-summary-no-content-leak', 'an EvalSummary task entry MUST NOT carry an output body'),
102
+ req('openwop.it.agent-eval-suite-shape.evalsummary-is-content-free-a-task-output-body-and-a-safety-finding-excerpt-are', 'SECURITY invariant eval-summary-no-content-leak', 'an EvalSummary task entry MUST NOT carry an output body'),
105
103
  ).toBe(false);
106
104
  // Negative: a safety finding carrying excerpted content rather than a {kind, severity} descriptor.
107
105
  expect(
108
106
  summary({ ...base, tasks: [{ taskId: 't1', score: 0.5, passed: false, safetyFindings: [{ kind: 'pii-leak', severity: 'high', excerpt: 'SSN 123-45-6789' }] }] }),
109
- why('SECURITY invariant eval-summary-no-content-leak', 'a safetyFinding MUST NOT carry excerpted content'),
107
+ req('openwop.it.agent-eval-suite-shape.evalsummary-is-content-free-a-task-output-body-and-a-safety-finding-excerpt-are', 'SECURITY invariant eval-summary-no-content-leak', 'a safetyFinding MUST NOT carry excerpted content'),
110
108
  ).toBe(false);
111
109
  });
112
110
  });
@@ -122,45 +120,45 @@ describe('agent-eval-suite-shape: eval event payloads (RFC 0081, server-free)',
122
120
  const completed = ajv.getSchema('payloads#/$defs/evalCompleted');
123
121
 
124
122
  it('eval.started validates a content-free start record and requires the suite provenance', () => {
125
- expect(started, 'the evalStarted $def MUST exist').toBeTruthy();
123
+ expect(started, req('openwop.it.agent-eval-suite-shape.eval-started-validates-a-content-free-start-record-and-requires-the-suite-proven', 'RFC 0081', 'the evalStarted $def MUST exist')).toBeTruthy();
126
124
  expect(
127
125
  started!({ suiteId: 'core.openwop.evals.support-resolver', suiteVersion: '1.0.0', taskCount: 12, modes: ['golden'] }),
128
- why('RFC 0081 §C', 'a conforming eval.started payload MUST validate'),
126
+ req('openwop.it.agent-eval-suite-shape.eval-started-validates-a-content-free-start-record-and-requires-the-suite-proven', 'RFC 0081 §C', 'a conforming eval.started payload MUST validate'),
129
127
  ).toBe(true);
130
128
  expect(
131
129
  started!({ suiteId: 'core.openwop.evals.x' }),
132
- why('RFC 0081 §C', 'eval.started without suiteVersion/taskCount/modes MUST be rejected'),
130
+ req('openwop.it.agent-eval-suite-shape.eval-started-validates-a-content-free-start-record-and-requires-the-suite-proven', 'RFC 0081 §C', 'eval.started without suiteVersion/taskCount/modes MUST be rejected'),
133
131
  ).toBe(false);
134
132
  });
135
133
 
136
134
  it('eval.scored validates a content-free per-task score and requires score + passed', () => {
137
- expect(scored, 'the evalScored $def MUST exist').toBeTruthy();
135
+ expect(scored, req('openwop.it.agent-eval-suite-shape.eval-scored-validates-a-content-free-per-task-score-and-requires-score-passed', 'RFC 0081', 'the evalScored $def MUST exist')).toBeTruthy();
138
136
  expect(
139
137
  scored!({ taskId: 'refund-window', score: 0.9, passed: true, costUsd: 0.012 }),
140
- why('RFC 0081 §C', 'a conforming eval.scored payload MUST validate'),
138
+ req('openwop.it.agent-eval-suite-shape.eval-scored-validates-a-content-free-per-task-score-and-requires-score-passed', 'RFC 0081 §C', 'a conforming eval.scored payload MUST validate'),
141
139
  ).toBe(true);
142
140
  expect(
143
141
  scored!({ taskId: 'refund-window' }),
144
- why('RFC 0081 §C', 'eval.scored without score/passed MUST be rejected'),
142
+ req('openwop.it.agent-eval-suite-shape.eval-scored-validates-a-content-free-per-task-score-and-requires-score-passed', 'RFC 0081 §C', 'eval.scored without score/passed MUST be rejected'),
145
143
  ).toBe(false);
146
144
  });
147
145
 
148
146
  it('eval.completed validates a content-free aggregate record', () => {
149
- expect(completed, 'the evalCompleted $def MUST exist').toBeTruthy();
147
+ expect(completed, req('openwop.it.agent-eval-suite-shape.eval-completed-validates-a-content-free-aggregate-record', 'RFC 0081', 'the evalCompleted $def MUST exist')).toBeTruthy();
150
148
  expect(
151
149
  completed!({ aggregateScore: 0.86, passed: true, taskCount: 12, passedCount: 11, regressionVsBaseline: 0.04 }),
152
- why('RFC 0081 §C', 'a conforming eval.completed payload MUST validate'),
150
+ req('openwop.it.agent-eval-suite-shape.eval-completed-validates-a-content-free-aggregate-record', 'RFC 0081 §C', 'a conforming eval.completed payload MUST validate'),
153
151
  ).toBe(true);
154
152
  expect(
155
153
  completed!({ aggregateScore: 2 }),
156
- why('RFC 0081 §C', 'eval.completed with an out-of-range aggregateScore MUST be rejected'),
154
+ req('openwop.it.agent-eval-suite-shape.eval-completed-validates-a-content-free-aggregate-record', 'RFC 0081 §C', 'eval.completed with an out-of-range aggregateScore MUST be rejected'),
157
155
  ).toBe(false);
158
156
  });
159
157
 
160
158
  it('all three eval event names appear in the RunEventType enum', () => {
161
159
  const runEvent = loadSchema('run-event.schema.json');
162
160
  const enumVals = (runEvent.$defs as Record<string, { enum?: string[] }>).RunEventType?.enum ?? [];
163
- expect(enumVals).toContain('eval.started');
161
+ expect(enumVals, req('openwop.it.agent-eval-suite-shape.all-three-eval-event-names-appear-in-the-runeventtype-enum', 'RFC 0081', 'all three eval event names appear in the RunEventType enum')).toContain('eval.started');
164
162
  expect(enumVals).toContain('eval.scored');
165
163
  expect(enumVals).toContain('eval.completed');
166
164
  });
@@ -20,10 +20,11 @@
20
20
  */
21
21
 
22
22
  import { describe, it, expect } from 'vitest';
23
- import { driver } from '../lib/driver.js';
24
23
  import { behaviorGate } from '../lib/behavior-gate.js';
25
24
  import { readLiveRuntimeCap, invokeLive } from '../lib/liveRuntime.js';
26
25
  import { queryTestEvents, isEventLogSeamAvailable, resetTestSeam } from '../lib/event-log-query.js';
26
+ import { req } from '../lib/requirement-ids.js';
27
+ import { softSkip } from '../lib/soft-skip.js';
27
28
 
28
29
  const DISALLOWED_TOOL = 'conformance-disallowed-tool';
29
30
 
@@ -32,12 +33,12 @@ describe('agent-live-allowlist-enforced (RFC 0077 §F-1)', () => {
32
33
  const cap = await readLiveRuntimeCap();
33
34
  if (!behaviorGate('openwop-live-allowlist-enforced', cap?.supported === true)) return;
34
35
 
35
- if (!(await isEventLogSeamAvailable())) return; // soft-skip
36
+ if (!(await isEventLogSeamAvailable())) return softSkip('blocked', 'precondition not met — `!(await isEventLogSeamAvailable())` returned early (soft-skip) (seam, prior step, or fixture unavailable)'); // soft-skip
36
37
  const res = await invokeLive({ source: 'run-api', attemptTool: DISALLOWED_TOOL });
37
- if (res === null || !res.runId) return; // seam/hook absent — soft-skip
38
+ if (res === null || !res.runId) return softSkip('blocked', 'precondition not met — `res === null || !res.runId` returned early (seam/hook absent — soft-skip) (seam, prior step, or fixture unavailable)'); // seam/hook absent — soft-skip
38
39
 
39
40
  const q = await queryTestEvents(res.runId, { type: 'agent.toolCalled' });
40
- if (!q.ok) return;
41
+ if (!q.ok) return softSkip('blocked', 'precondition not met — `!q.ok` returned early (seam, prior step, or fixture unavailable)');
41
42
 
42
43
  const calledDisallowed = q.events.some((e) => {
43
44
  const tool = e.payload.tool ?? e.payload.toolId ?? e.payload.name;
@@ -45,7 +46,7 @@ describe('agent-live-allowlist-enforced (RFC 0077 §F-1)', () => {
45
46
  });
46
47
  expect(
47
48
  calledDisallowed === false,
48
- driver.describe('RFC 0077 §F-1 / RFC 0002 §A14', 'a live invocation MUST NOT call a tool outside the agent toolAllowlist'),
49
+ req('openwop.it.agent-live-allowlist-enforced.does-not-call-a-tool-outside-the-agent-toolallowlist', 'RFC 0077 §F-1 / RFC 0002 §A14', 'a live invocation MUST NOT call a tool outside the agent toolAllowlist'),
49
50
  ).toBe(true);
50
51
 
51
52
  await resetTestSeam();
@@ -21,10 +21,11 @@
21
21
  */
22
22
 
23
23
  import { describe, it, expect } from 'vitest';
24
- import { driver } from '../lib/driver.js';
25
24
  import { behaviorGate } from '../lib/behavior-gate.js';
26
25
  import { readLiveRuntimeCap, invokeLive } from '../lib/liveRuntime.js';
27
26
  import { queryTestEvents, isEventLogSeamAvailable, resetTestSeam } from '../lib/event-log-query.js';
27
+ import { req } from '../lib/requirement-ids.js';
28
+ import { softSkip } from '../lib/soft-skip.js';
28
29
 
29
30
  const SOURCES = ['workflow-node', 'run-api', 'chat-mention'];
30
31
  const OUTCOMES = ['completed', 'handed-off', 'escalated', 'refused', 'failed'];
@@ -35,21 +36,21 @@ describe('agent-live-invocation-bracket (RFC 0077 §E)', () => {
35
36
  const cap = await readLiveRuntimeCap();
36
37
  if (!behaviorGate('openwop-live-invocation-bracket', cap?.supported === true)) return;
37
38
 
38
- if (!(await isEventLogSeamAvailable())) return; // event-log seam absent — soft-skip
39
+ if (!(await isEventLogSeamAvailable())) return softSkip('blocked', 'precondition not met — `!(await isEventLogSeamAvailable())` returned early (event-log seam absent — soft-skip) (seam, prior step, or fixture unavailable)'); // event-log seam absent — soft-skip
39
40
  const res = await invokeLive({ source: 'run-api' });
40
- if (res === null || !res.runId) return; // live-invoke seam absent — soft-skip
41
+ if (res === null || !res.runId) return softSkip('blocked', 'precondition not met — `res === null || !res.runId` returned early (live-invoke seam absent — soft-skip) (seam, prior step, or fixture unavailable)'); // live-invoke seam absent — soft-skip
41
42
 
42
43
  const q = await queryTestEvents(res.runId);
43
- if (!q.ok) return;
44
+ if (!q.ok) return softSkip('blocked', 'precondition not met — `!q.ok` returned early (seam, prior step, or fixture unavailable)');
44
45
  const events = q.events.slice().sort((a, b) => a.sequence - b.sequence);
45
46
 
46
47
  const started = events.filter((e) => e.type === 'agent.invocation.started');
47
48
  const completed = events.filter((e) => e.type === 'agent.invocation.completed');
48
49
  expect(
49
50
  started.length >= 1 && completed.length >= 1,
50
- driver.describe('multi-agent-execution.md §"Live manifest dispatch"', 'a live invocation MUST emit agent.invocation.started + agent.invocation.completed'),
51
+ req('openwop.it.agent-live-invocation-bracket.brackets-a-live-invocation-with-started-first-completed-last-matching-invocation', 'multi-agent-execution.md §"Live manifest dispatch"', 'a live invocation MUST emit agent.invocation.started + agent.invocation.completed'),
51
52
  ).toBe(true);
52
- if (started.length === 0 || completed.length === 0) return;
53
+ if (started.length === 0 || completed.length === 0) return softSkip('blocked', 'precondition not met — `started.length === 0 || completed.length === 0` returned early (seam, prior step, or fixture unavailable)');
53
54
 
54
55
  const start = started[0]!;
55
56
  const end = completed[completed.length - 1]!;
@@ -58,11 +59,11 @@ describe('agent-live-invocation-bracket (RFC 0077 §E)', () => {
58
59
  const agentScoped = events.filter((e) => AGENT_SCOPED(e.type));
59
60
  expect(
60
61
  agentScoped[0]?.type === 'agent.invocation.started',
61
- driver.describe('RFC 0077 §E', 'agent.invocation.started MUST be the first agent-scoped event of the invocation'),
62
+ req('openwop.it.agent-live-invocation-bracket.brackets-a-live-invocation-with-started-first-completed-last-matching-invocation', 'RFC 0077 §E', 'agent.invocation.started MUST be the first agent-scoped event of the invocation'),
62
63
  ).toBe(true);
63
64
  expect(
64
65
  agentScoped[agentScoped.length - 1]?.type === 'agent.invocation.completed',
65
- driver.describe('RFC 0077 §E', 'agent.invocation.completed MUST be the last agent-scoped event of the invocation'),
66
+ req('openwop.it.agent-live-invocation-bracket.brackets-a-live-invocation-with-started-first-completed-last-matching-invocation', 'RFC 0077 §E', 'agent.invocation.completed MUST be the last agent-scoped event of the invocation'),
66
67
  ).toBe(true);
67
68
 
68
69
  // Matching invocationId across the bracket.
@@ -70,17 +71,17 @@ describe('agent-live-invocation-bracket (RFC 0077 §E)', () => {
70
71
  const endId = end.payload.invocationId;
71
72
  expect(
72
73
  typeof startId === 'string' && startId === endId,
73
- driver.describe('run-event-payloads.schema.json#agentInvocation*', 'the bracket MUST share one invocationId'),
74
+ req('openwop.it.agent-live-invocation-bracket.brackets-a-live-invocation-with-started-first-completed-last-matching-invocation', 'run-event-payloads.schema.json#agentInvocation*', 'the bracket MUST share one invocationId'),
74
75
  ).toBe(true);
75
76
 
76
77
  // Enum discipline.
77
78
  expect(
78
79
  typeof start.payload.source === 'string' && SOURCES.includes(start.payload.source as string),
79
- driver.describe('run-event-payloads.schema.json#agentInvocationStarted', 'source MUST be workflow-node|run-api|chat-mention'),
80
+ req('openwop.it.agent-live-invocation-bracket.brackets-a-live-invocation-with-started-first-completed-last-matching-invocation', 'run-event-payloads.schema.json#agentInvocationStarted', 'source MUST be workflow-node|run-api|chat-mention'),
80
81
  ).toBe(true);
81
82
  expect(
82
83
  typeof end.payload.outcome === 'string' && OUTCOMES.includes(end.payload.outcome as string),
83
- driver.describe('run-event-payloads.schema.json#agentInvocationCompleted', 'outcome MUST be in the closed enum'),
84
+ req('openwop.it.agent-live-invocation-bracket.brackets-a-live-invocation-with-started-first-completed-last-matching-invocation', 'run-event-payloads.schema.json#agentInvocationCompleted', 'outcome MUST be in the closed enum'),
84
85
  ).toBe(true);
85
86
 
86
87
  // Content-free: identifiers + metadata only, never prompt/result body.
@@ -88,7 +89,7 @@ describe('agent-live-invocation-bracket (RFC 0077 §E)', () => {
88
89
  for (const forbidden of ['prompt', 'result', 'body', 'input', 'output', 'apiKey', 'secret', 'credentials', 'token']) {
89
90
  expect(
90
91
  !(forbidden in evt.payload),
91
- driver.describe('RFC 0077', `agent.invocation.* MUST be content-free (no ${forbidden})`),
92
+ req('openwop.it.agent-live-invocation-bracket.brackets-a-live-invocation-with-started-first-completed-last-matching-invocation', 'RFC 0077', `agent.invocation.* MUST be content-free (no ${forbidden})`),
92
93
  ).toBe(true);
93
94
  }
94
95
  }
@@ -28,9 +28,7 @@ import { join } from 'node:path';
28
28
  import Ajv2020 from 'ajv/dist/2020.js';
29
29
  import addFormats from 'ajv-formats';
30
30
  import { SCHEMAS_DIR } from '../lib/paths.js';
31
-
32
- /** Server-free assertion-message helper (mirrors driver.describe's "spec — requirement" shape without requiring OPENWOP_BASE_URL). */
33
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
31
+ import { req } from '../lib/requirement-ids.js';
34
32
 
35
33
  function loadSchema(name: string): Record<string, unknown> {
36
34
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -43,12 +41,12 @@ describe('agent-live-runtime-shape: capability advertisement (RFC 0077, server-f
43
41
  const live = agents?.properties?.liveRuntime;
44
42
  expect(
45
43
  live,
46
- why('capabilities.md §agents', 'agents.liveRuntime MUST be declared'),
44
+ req('openwop.it.agent-live-runtime-shape.the-capabilities-schema-declares-agents-liveruntime-with-its-sub-flags', 'capabilities.md §agents', 'agents.liveRuntime MUST be declared'),
47
45
  ).toBeDefined();
48
46
  for (const flag of ['supported', 'structuredOutput', 'confidenceEscalation', 'sources']) {
49
47
  expect(
50
48
  live?.properties?.[flag],
51
- why('multi-agent-execution.md §Live manifest dispatch', `agents.liveRuntime.${flag} MUST be declared`),
49
+ req('openwop.it.agent-live-runtime-shape.the-capabilities-schema-declares-agents-liveruntime-with-its-sub-flags', 'multi-agent-execution.md §Live manifest dispatch', `agents.liveRuntime.${flag} MUST be declared`),
52
50
  ).toBeDefined();
53
51
  }
54
52
  });
@@ -64,35 +62,35 @@ describe('agent-live-runtime-shape: invocation event payloads (RFC 0077, server-
64
62
  const completed = ajv.getSchema('payloads#/$defs/agentInvocationCompleted');
65
63
 
66
64
  it('agent.invocation.started validates a content-free start record and requires source', () => {
67
- expect(started, 'the agentInvocationStarted $def MUST exist').toBeTruthy();
65
+ expect(started, req('openwop.it.agent-live-runtime-shape.agent-invocation-started-validates-a-content-free-start-record-and-requires-sour', 'RFC 0077', 'the agentInvocationStarted $def MUST exist')).toBeTruthy();
68
66
  expect(
69
67
  started!({ invocationId: 'inv-1', agentId: 'vendor.acme.review.code-reviewer', source: 'run-api', modelClass: 'coding', toolSurfaceCount: 3, memoryBound: false }),
70
- why('RFC 0077 §C', 'a conforming agent.invocation.started payload MUST validate'),
68
+ req('openwop.it.agent-live-runtime-shape.agent-invocation-started-validates-a-content-free-start-record-and-requires-sour', 'RFC 0077 §C', 'a conforming agent.invocation.started payload MUST validate'),
71
69
  ).toBe(true);
72
70
  // Negative: missing source — every invocation must record its entry point.
73
71
  expect(
74
72
  started!({ invocationId: 'inv-1', agentId: 'vendor.acme.review.code-reviewer' }),
75
- why('RFC 0077 §C', 'agent.invocation.started without source MUST be rejected'),
73
+ req('openwop.it.agent-live-runtime-shape.agent-invocation-started-validates-a-content-free-start-record-and-requires-sour', 'RFC 0077 §C', 'agent.invocation.started without source MUST be rejected'),
76
74
  ).toBe(false);
77
75
  });
78
76
 
79
77
  it('agent.invocation.completed validates a content-free outcome record and pins the outcome enum', () => {
80
- expect(completed, 'the agentInvocationCompleted $def MUST exist').toBeTruthy();
78
+ expect(completed, req('openwop.it.agent-live-runtime-shape.agent-invocation-completed-validates-a-content-free-outcome-record-and-pins-the', 'RFC 0077', 'the agentInvocationCompleted $def MUST exist')).toBeTruthy();
81
79
  expect(
82
80
  completed!({ invocationId: 'inv-1', agentId: 'vendor.acme.review.code-reviewer', outcome: 'completed', schemaValidated: true, confidence: 0.91 }),
83
- why('RFC 0077 §C', 'a conforming agent.invocation.completed payload MUST validate'),
81
+ req('openwop.it.agent-live-runtime-shape.agent-invocation-completed-validates-a-content-free-outcome-record-and-pins-the', 'RFC 0077 §C', 'a conforming agent.invocation.completed payload MUST validate'),
84
82
  ).toBe(true);
85
83
  // Negative: out-of-enum outcome — the canonical value is `completed`, not `done`.
86
84
  expect(
87
85
  completed!({ invocationId: 'inv-1', agentId: 'a', outcome: 'done' }),
88
- why('RFC 0077 §C', 'agent.invocation.completed with an out-of-enum outcome MUST be rejected'),
86
+ req('openwop.it.agent-live-runtime-shape.agent-invocation-completed-validates-a-content-free-outcome-record-and-pins-the', 'RFC 0077 §C', 'agent.invocation.completed with an out-of-enum outcome MUST be rejected'),
89
87
  ).toBe(false);
90
88
  });
91
89
 
92
90
  it('both invocation event names appear in the RunEventType enum', () => {
93
91
  const runEvent = loadSchema('run-event.schema.json');
94
92
  const enumVals = (runEvent.$defs as Record<string, { enum?: string[] }>).RunEventType?.enum ?? [];
95
- expect(enumVals).toContain('agent.invocation.started');
93
+ expect(enumVals, req('openwop.it.agent-live-runtime-shape.both-invocation-event-names-appear-in-the-runeventtype-enum', 'RFC 0077', 'both invocation event names appear in the RunEventType enum')).toContain('agent.invocation.started');
96
94
  expect(enumVals).toContain('agent.invocation.completed');
97
95
  });
98
96
  });