@openwop/openwop-conformance 1.162.0 → 2.0.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (553) hide show
  1. package/README.md +11 -2
  2. package/dist/cli.js +54 -1
  3. package/dist/lib/paths.js +25 -3
  4. package/dist/lib/requirement-ids.js +34 -4
  5. package/dist/lib/scenario-disposition.js +1 -0
  6. package/dist/lib/spec-coherence.js +13 -32
  7. package/dist/spec-artifacts.lock.json +5 -0
  8. package/package.json +11 -33
  9. package/requirements.json +20303 -11809
  10. package/scenario-majors.json +1343 -0
  11. package/schemas/CORPUS-STAMP.json +138 -6
  12. package/src/cli.ts +47 -1
  13. package/src/global-setup.ts +3 -2
  14. package/src/lib/corpus-stamp.ts +29 -1
  15. package/src/lib/paths.ts +25 -3
  16. package/src/lib/requirement-ids.ts +33 -4
  17. package/src/lib/scenario-disposition.ts +1 -0
  18. package/src/lib/spec-coherence.ts +15 -32
  19. package/src/scenarios/a2a-1-0-agent-card.test.ts +17 -16
  20. package/src/scenarios/a2a-1-0-task-roundtrip.test.ts +11 -10
  21. package/src/scenarios/a2a-card-runtime-consistency.test.ts +18 -17
  22. package/src/scenarios/a2a-peer-authority.test.ts +7 -6
  23. package/src/scenarios/a2a-task-roundtrip.test.ts +30 -29
  24. package/src/scenarios/a2a-version-negotiation.test.ts +16 -14
  25. package/src/scenarios/a2ui-surface-degrades.test.ts +5 -3
  26. package/src/scenarios/a2ui-surface-delta-transport.test.ts +35 -33
  27. package/src/scenarios/a2ui-surface-replay.test.ts +6 -4
  28. package/src/scenarios/a2ui-surface-shape.test.ts +11 -10
  29. package/src/scenarios/a2ui-surface-version-refusal.test.ts +6 -4
  30. package/src/scenarios/a2ui-untrusted-blocks-approval.test.ts +5 -3
  31. package/src/scenarios/agent-capability-degraded-projection.test.ts +12 -11
  32. package/src/scenarios/agent-channel-dispatch.test.ts +18 -16
  33. package/src/scenarios/agent-deployment-lifecycle.test.ts +20 -19
  34. package/src/scenarios/agent-deployment-shape.test.ts +22 -24
  35. package/src/scenarios/agent-eval-run.test.ts +19 -18
  36. package/src/scenarios/agent-eval-suite-shape.test.ts +20 -22
  37. package/src/scenarios/agent-live-allowlist-enforced.test.ts +6 -5
  38. package/src/scenarios/agent-live-invocation-bracket.test.ts +13 -12
  39. package/src/scenarios/agent-live-runtime-shape.test.ts +10 -12
  40. package/src/scenarios/agent-live-structured-output.test.ts +7 -6
  41. package/src/scenarios/agent-loop-iteration-monotonic.test.ts +3 -3
  42. package/src/scenarios/agent-loop-stateful-resume.test.ts +2 -2
  43. package/src/scenarios/agent-loop-version5-shape.test.ts +4 -4
  44. package/src/scenarios/agent-loop-workspace-snapshot.test.ts +3 -3
  45. package/src/scenarios/agent-manifest-role-profile.test.ts +9 -9
  46. package/src/scenarios/agent-manifest-runtime.test.ts +13 -12
  47. package/src/scenarios/agent-org-chart-scoping.test.ts +14 -13
  48. package/src/scenarios/agent-org-chart-shape.test.ts +11 -13
  49. package/src/scenarios/agent-platform-aggregate-evidence.test.ts +5 -4
  50. package/src/scenarios/agent-platform-profile.test.ts +18 -19
  51. package/src/scenarios/agent-requires-capabilities-shape.test.ts +4 -4
  52. package/src/scenarios/agent-roster-attribution.test.ts +18 -17
  53. package/src/scenarios/agent-roster-shape.test.ts +17 -19
  54. package/src/scenarios/agent-verifier-shape.test.ts +11 -11
  55. package/src/scenarios/agentConfidenceEscalation.test.ts +2 -1
  56. package/src/scenarios/agentMemoryCrossTenantIsolation.test.ts +6 -5
  57. package/src/scenarios/agentMemoryRedactionContract.test.ts +2 -1
  58. package/src/scenarios/agentMemoryRoundTrip.test.ts +2 -1
  59. package/src/scenarios/agentMemoryTtlExpiry.test.ts +4 -3
  60. package/src/scenarios/agentMessageReducer.test.ts +2 -1
  61. package/src/scenarios/agentMetadata.test.ts +2 -1
  62. package/src/scenarios/agentPackCatalog.test.ts +23 -21
  63. package/src/scenarios/agentPackExport.test.ts +4 -2
  64. package/src/scenarios/agentPackHandoffSchemaValidation.test.ts +5 -4
  65. package/src/scenarios/agentPackInstall.test.ts +4 -2
  66. package/src/scenarios/agentPackProvenance.test.ts +2 -1
  67. package/src/scenarios/agentReasoningEvents.test.ts +3 -2
  68. package/src/scenarios/agentReasoningStreaming.test.ts +11 -10
  69. package/src/scenarios/agents-run-tool-allowlist.test.ts +14 -12
  70. package/src/scenarios/ai-envelope-shape.test.ts +31 -29
  71. package/src/scenarios/aiEnvelope.capBreached.test.ts +26 -24
  72. package/src/scenarios/aiEnvelope.contractRefusal.test.ts +36 -34
  73. package/src/scenarios/aiEnvelope.correlationReplay.test.ts +17 -15
  74. package/src/scenarios/aiEnvelope.redaction.test.ts +22 -20
  75. package/src/scenarios/aiEnvelope.schemaDrift.test.ts +18 -16
  76. package/src/scenarios/aiEnvelope.trustBoundaryPropagation.test.ts +38 -36
  77. package/src/scenarios/aiEnvelope.universalKinds.test.ts +31 -29
  78. package/src/scenarios/aiproviders-input-shape.test.ts +5 -5
  79. package/src/scenarios/aiproviders-realtimevoice-shape.test.ts +14 -16
  80. package/src/scenarios/aiproviders-selfhosted-honesty.test.ts +6 -4
  81. package/src/scenarios/aiproviders-selfhosted-shape.test.ts +15 -17
  82. package/src/scenarios/aiproviders-speechsynth-shape.test.ts +6 -8
  83. package/src/scenarios/aiproviders-subscription-scope.test.ts +7 -8
  84. package/src/scenarios/anonymous-actor-audit-opaque.test.ts +9 -8
  85. package/src/scenarios/anonymous-actor-default-deny.test.ts +10 -9
  86. package/src/scenarios/anonymous-actor-egress-guarded.test.ts +6 -5
  87. package/src/scenarios/anonymous-actor-no-secret-reach.test.ts +7 -6
  88. package/src/scenarios/anonymous-actor-shape.test.ts +17 -19
  89. package/src/scenarios/anonymous-actor-write-gated.test.ts +9 -8
  90. package/src/scenarios/append-ordering.test.ts +7 -5
  91. package/src/scenarios/approval-gate-events.test.ts +4 -3
  92. package/src/scenarios/approval-gate-flow.test.ts +4 -3
  93. package/src/scenarios/approval-payload.test.ts +5 -4
  94. package/src/scenarios/artifact-auth.test.ts +7 -6
  95. package/src/scenarios/artifact-type-pack-install.test.ts +6 -6
  96. package/src/scenarios/artifact-type-pack-manifest-validation.test.ts +9 -8
  97. package/src/scenarios/artifact-type-registration-source.test.ts +20 -20
  98. package/src/scenarios/artifact-type-store-emission.test.ts +15 -18
  99. package/src/scenarios/artifact-type-store-without-render.test.ts +4 -4
  100. package/src/scenarios/audit-log-integrity.test.ts +8 -6
  101. package/src/scenarios/auth-api-key-rotation.test.ts +11 -9
  102. package/src/scenarios/auth-mtls.test.ts +22 -20
  103. package/src/scenarios/auth-oauth2-client-credentials.test.ts +16 -14
  104. package/src/scenarios/auth-oidc-user-bearer.test.ts +26 -24
  105. package/src/scenarios/auth-saml-profile.test.ts +14 -12
  106. package/src/scenarios/auth-scim-profile.test.ts +3 -2
  107. package/src/scenarios/auth-subject-link-key-class.test.ts +8 -7
  108. package/src/scenarios/auth-subject-link.test.ts +11 -10
  109. package/src/scenarios/auth.test.ts +5 -4
  110. package/src/scenarios/authorization-fail-closed.test.ts +3 -2
  111. package/src/scenarios/authorization-roles-shape.test.ts +9 -7
  112. package/src/scenarios/blob-cross-tenant-isolation.test.ts +8 -6
  113. package/src/scenarios/blob-presign-expiry.test.ts +12 -10
  114. package/src/scenarios/blob-roundtrip.test.ts +0 -0
  115. package/src/scenarios/budget-enforcement.test.ts +15 -14
  116. package/src/scenarios/budget-policy-shape.test.ts +18 -19
  117. package/src/scenarios/bulk-cancel.test.ts +9 -8
  118. package/src/scenarios/byok-auth-modes.test.ts +13 -14
  119. package/src/scenarios/byok-roundtrip.test.ts +12 -10
  120. package/src/scenarios/cache-cross-tenant-isolation.test.ts +8 -6
  121. package/src/scenarios/cache-ttl-expiry.test.ts +7 -5
  122. package/src/scenarios/callai-multimodal.test.ts +5 -3
  123. package/src/scenarios/cancellation.test.ts +6 -5
  124. package/src/scenarios/cap-breach.test.ts +15 -14
  125. package/src/scenarios/capability-arm-witness.test.ts +5 -3
  126. package/src/scenarios/certification-bundle-non-vacuous.test.ts +20 -19
  127. package/src/scenarios/certification-bundle-redaction.test.ts +11 -10
  128. package/src/scenarios/certification-bundle-v2.test.ts +11 -10
  129. package/src/scenarios/chain-compensation-expansion.test.ts +14 -13
  130. package/src/scenarios/chain-produced-var-roundtrip.test.ts +13 -14
  131. package/src/scenarios/chain-subchain-cycle-rejected.test.ts +9 -10
  132. package/src/scenarios/chain-subchain-fanout.test.ts +8 -9
  133. package/src/scenarios/chain-subchain-sibling.test.ts +14 -16
  134. package/src/scenarios/channel-presence-behavioral.test.ts +9 -7
  135. package/src/scenarios/channel-presence-shape.test.ts +11 -12
  136. package/src/scenarios/channel-ttl.test.ts +6 -5
  137. package/src/scenarios/chat-card-pack-execution.test.ts +4 -4
  138. package/src/scenarios/chat-card-pack-manifest-validation.test.ts +9 -8
  139. package/src/scenarios/commitment-fired.test.ts +6 -5
  140. package/src/scenarios/compensation-behavior.test.ts +24 -23
  141. package/src/scenarios/compensation-recovery.test.ts +28 -27
  142. package/src/scenarios/configurable-schema.test.ts +8 -6
  143. package/src/scenarios/conformance-advertised-seam-required.test.ts +6 -5
  144. package/src/scenarios/conformance-execution-witness.test.ts +9 -8
  145. package/src/scenarios/connection-pack-apihosts.test.ts +19 -17
  146. package/src/scenarios/connection-pack-manifest-valid.test.ts +12 -11
  147. package/src/scenarios/connection-pack-no-credential-material.test.ts +8 -6
  148. package/src/scenarios/connection-pack-reach-exclusive.test.ts +5 -4
  149. package/src/scenarios/connection-pack-write-reconsent.test.ts +6 -4
  150. package/src/scenarios/connection-provider-resolution.test.ts +18 -16
  151. package/src/scenarios/connector-manifest-validity.test.ts +8 -7
  152. package/src/scenarios/context-budget-transcript-bound.test.ts +17 -15
  153. package/src/scenarios/context-summarization-replay.test.ts +14 -12
  154. package/src/scenarios/contract-provenance.test.ts +18 -18
  155. package/src/scenarios/conversation-turn-model-provenance-shape.test.ts +14 -15
  156. package/src/scenarios/conversationCapabilityNegotiation.test.ts +2 -1
  157. package/src/scenarios/conversationLifecycle.test.ts +2 -1
  158. package/src/scenarios/conversationReplayDeterminism.test.ts +4 -2
  159. package/src/scenarios/conversationVsLegacySuspend.test.ts +2 -1
  160. package/src/scenarios/core-standard-profile.test.ts +8 -9
  161. package/src/scenarios/cost-attribution.test.ts +23 -21
  162. package/src/scenarios/credential-payload-redaction.test.ts +4 -3
  163. package/src/scenarios/credentials-capability-shape.test.ts +5 -4
  164. package/src/scenarios/cross-engine-append-behavior.test.ts +11 -10
  165. package/src/scenarios/cross-engine-append-ordering.test.ts +4 -3
  166. package/src/scenarios/cross-host-ancestry-endpoint.test.ts +11 -10
  167. package/src/scenarios/cross-host-causation-shape.test.ts +7 -6
  168. package/src/scenarios/cross-workspace-isolation.test.ts +4 -3
  169. package/src/scenarios/data-residency-admission.test.ts +15 -14
  170. package/src/scenarios/deadletter-capability-shape.test.ts +6 -4
  171. package/src/scenarios/deadletter-retry-exhaustion.test.ts +4 -3
  172. package/src/scenarios/debug-bundle-truncation.test.ts +9 -7
  173. package/src/scenarios/debugBundle.test.ts +25 -23
  174. package/src/scenarios/discovery-families-view.test.ts +5 -4
  175. package/src/scenarios/discovery.test.ts +30 -29
  176. package/src/scenarios/dispatch-cross-worker-handoff.test.ts +10 -8
  177. package/src/scenarios/dispatch-fanout-parallel.test.ts +24 -22
  178. package/src/scenarios/dispatch-input-mapping.test.ts +12 -10
  179. package/src/scenarios/dispatch-output-mapping.test.ts +9 -7
  180. package/src/scenarios/dispatch-per-item-input.test.ts +22 -20
  181. package/src/scenarios/dispatchLoop.test.ts +3 -2
  182. package/src/scenarios/distillation-index-roundtrip.test.ts +3 -3
  183. package/src/scenarios/distillation-secret-carryforward.test.ts +2 -2
  184. package/src/scenarios/distillation-shape.test.ts +4 -4
  185. package/src/scenarios/distillation-stable-archive.test.ts +6 -6
  186. package/src/scenarios/distillation-token-budget.test.ts +5 -5
  187. package/src/scenarios/durability-poison-exhaustion.test.ts +7 -6
  188. package/src/scenarios/egress-audience-binding.test.ts +11 -10
  189. package/src/scenarios/egress-decision-content-free.test.ts +6 -5
  190. package/src/scenarios/egress-provenance-shape.test.ts +17 -18
  191. package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +27 -25
  192. package/src/scenarios/envelope-nl-to-format-engaged.test.ts +19 -17
  193. package/src/scenarios/envelope-reasoning-secret-redaction.test.ts +28 -26
  194. package/src/scenarios/envelope-reasoning-shape.test.ts +19 -17
  195. package/src/scenarios/envelope-recovery-applied.test.ts +24 -22
  196. package/src/scenarios/envelope-refusal-shape.test.ts +31 -29
  197. package/src/scenarios/envelope-rendering-hint.test.ts +5 -4
  198. package/src/scenarios/envelope-retry-attempted.test.ts +33 -31
  199. package/src/scenarios/envelope-retry-exhausted.test.ts +22 -20
  200. package/src/scenarios/envelope-tier-one-subset-static.test.ts +9 -7
  201. package/src/scenarios/envelope-truncated.test.ts +19 -17
  202. package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +19 -17
  203. package/src/scenarios/envelope-variant-discriminator-static.test.ts +4 -3
  204. package/src/scenarios/errors.test.ts +20 -19
  205. package/src/scenarios/eventOrdering.test.ts +16 -14
  206. package/src/scenarios/exec-not-protocol-tier.test.ts +5 -7
  207. package/src/scenarios/experimental-tier-shape.test.ts +17 -15
  208. package/src/scenarios/export-bundle-portability.test.ts +17 -17
  209. package/src/scenarios/failure-path.test.ts +7 -6
  210. package/src/scenarios/feedback-capability-shape.test.ts +4 -3
  211. package/src/scenarios/feedback-correction-redaction.test.ts +2 -1
  212. package/src/scenarios/feedback-cross-tenant-isolation.test.ts +2 -1
  213. package/src/scenarios/feedback-fork-not-copied.test.ts +3 -2
  214. package/src/scenarios/feedback-on-terminal-run.test.ts +3 -2
  215. package/src/scenarios/feedback-record-and-list.test.ts +2 -1
  216. package/src/scenarios/feedback-unsupported-501.test.ts +2 -1
  217. package/src/scenarios/fixtures-gating.test.ts +29 -28
  218. package/src/scenarios/fixtures-valid.test.ts +16 -15
  219. package/src/scenarios/form-content-instantiation.test.ts +15 -14
  220. package/src/scenarios/frontend-plugin-packs.test.ts +29 -27
  221. package/src/scenarios/fs-path-traversal.test.ts +14 -12
  222. package/src/scenarios/goal-standing-continuation.test.ts +21 -21
  223. package/src/scenarios/grpc-transport.test.ts +9 -7
  224. package/src/scenarios/heartbeat-capability-shape.test.ts +3 -3
  225. package/src/scenarios/heartbeat-fires-once-per-tick.test.ts +2 -2
  226. package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +3 -3
  227. package/src/scenarios/heartbeat-runtime-bound.test.ts +2 -2
  228. package/src/scenarios/highConcurrency.test.ts +14 -13
  229. package/src/scenarios/host-callback-declaration.test.ts +8 -7
  230. package/src/scenarios/http-client-ssrf.test.ts +7 -5
  231. package/src/scenarios/i18n-negotiation.test.ts +14 -12
  232. package/src/scenarios/idempotency-concurrent-claim.test.ts +14 -13
  233. package/src/scenarios/idempotency-key-determinism.test.ts +20 -18
  234. package/src/scenarios/idempotency.test.ts +8 -7
  235. package/src/scenarios/idempotencyRetry.test.ts +13 -11
  236. package/src/scenarios/identity-owner-shape.test.ts +6 -5
  237. package/src/scenarios/identity-passthrough.test.ts +4 -3
  238. package/src/scenarios/interrupt-approval.test.ts +6 -5
  239. package/src/scenarios/interrupt-approver-routing.test.ts +15 -15
  240. package/src/scenarios/interrupt-auth-required-resume.test.ts +5 -3
  241. package/src/scenarios/interrupt-clarification.test.ts +4 -3
  242. package/src/scenarios/interrupt-external-event-correlation.test.ts +6 -5
  243. package/src/scenarios/interrupt-parent-child-cascade.test.ts +4 -3
  244. package/src/scenarios/interrupt-quorum-resolution.test.ts +5 -4
  245. package/src/scenarios/interrupt-token-matrix.test.ts +8 -6
  246. package/src/scenarios/interruptRace.test.ts +12 -10
  247. package/src/scenarios/kv-atomic-increment.test.ts +11 -9
  248. package/src/scenarios/kv-cas.test.ts +14 -12
  249. package/src/scenarios/kv-cross-tenant-isolation.test.ts +12 -10
  250. package/src/scenarios/kv-ttl-expiry.test.ts +7 -5
  251. package/src/scenarios/localized-content-delivery.test.ts +24 -26
  252. package/src/scenarios/maliciousManifest.test.ts +10 -8
  253. package/src/scenarios/mcp-2026-07-28-discover.test.ts +15 -14
  254. package/src/scenarios/mcp-cache-tenant-scope.test.ts +6 -5
  255. package/src/scenarios/mcp-current-auth-boundary.test.ts +7 -6
  256. package/src/scenarios/mcp-discoverability.test.ts +9 -7
  257. package/src/scenarios/mcp-extension-opacity.test.ts +7 -6
  258. package/src/scenarios/mcp-mrtr-roundtrip.test.ts +18 -17
  259. package/src/scenarios/mcp-server-elicitation-bridge.test.ts +13 -12
  260. package/src/scenarios/mcp-server-prompt-roundtrip.test.ts +11 -10
  261. package/src/scenarios/mcp-server-resource-roundtrip.test.ts +11 -10
  262. package/src/scenarios/mcp-server-sampling-bridge.test.ts +12 -11
  263. package/src/scenarios/mcp-server-tool-roundtrip.test.ts +14 -13
  264. package/src/scenarios/mcp-server-untrusted-args.test.ts +14 -13
  265. package/src/scenarios/mcp-stateless-request.test.ts +11 -10
  266. package/src/scenarios/mcp-tool-roundtrip.test.ts +4 -3
  267. package/src/scenarios/mcp-toolcall-redaction.test.ts +4 -3
  268. package/src/scenarios/mcp-version-negotiation.test.ts +15 -14
  269. package/src/scenarios/media-url-inline-cap.test.ts +21 -19
  270. package/src/scenarios/memory-attribution-emits-on-write.test.ts +5 -5
  271. package/src/scenarios/memory-attribution-no-content.test.ts +4 -4
  272. package/src/scenarios/memory-attribution-replay-stable.test.ts +4 -3
  273. package/src/scenarios/memory-attribution-shape.test.ts +4 -3
  274. package/src/scenarios/memory-attribution-tenant-scoped.test.ts +3 -3
  275. package/src/scenarios/memory-capability-model-shape.test.ts +14 -15
  276. package/src/scenarios/memory-compaction-event-emitted.test.ts +7 -6
  277. package/src/scenarios/memory-compaction-provenance-tag.test.ts +3 -2
  278. package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +7 -6
  279. package/src/scenarios/memory-consolidation-idempotent.test.ts +5 -4
  280. package/src/scenarios/memory-consolidation-shape.test.ts +9 -11
  281. package/src/scenarios/memory-degraded-projection.test.ts +10 -9
  282. package/src/scenarios/memory-injection-budget.test.ts +15 -14
  283. package/src/scenarios/metric-emission.test.ts +4 -3
  284. package/src/scenarios/model-capability-insufficient.test.ts +19 -17
  285. package/src/scenarios/model-capability-substituted.test.ts +20 -18
  286. package/src/scenarios/multi-agent-confidence-escalation.test.ts +12 -11
  287. package/src/scenarios/multi-agent-handoff-state-machine.test.ts +10 -9
  288. package/src/scenarios/multi-agent-memory-lifecycle.test.ts +11 -10
  289. package/src/scenarios/multi-node-ordering.test.ts +4 -3
  290. package/src/scenarios/multi-party-conversation-behavioral.test.ts +6 -6
  291. package/src/scenarios/multi-party-conversation-shape.test.ts +21 -23
  292. package/src/scenarios/multi-region-idempotency-behavior.test.ts +16 -15
  293. package/src/scenarios/multi-region-idempotency.test.ts +6 -5
  294. package/src/scenarios/node-failed-payload-shape.test.ts +5 -4
  295. package/src/scenarios/node-module-required-capabilities-shape.test.ts +10 -8
  296. package/src/scenarios/oauth-authorization-code-roundtrip.test.ts +5 -4
  297. package/src/scenarios/oauth-capability-shape.test.ts +5 -4
  298. package/src/scenarios/oauth-connector-redaction.test.ts +4 -3
  299. package/src/scenarios/openapi-resolved-paths.test.ts +6 -5
  300. package/src/scenarios/orchestratorConservativePath.test.ts +2 -1
  301. package/src/scenarios/orchestratorDispatch.test.ts +2 -1
  302. package/src/scenarios/orchestratorTermination.test.ts +2 -1
  303. package/src/scenarios/org-position-no-authority-escalation.test.ts +2 -2
  304. package/src/scenarios/otel-collector-canary-inspection.test.ts +8 -7
  305. package/src/scenarios/otel-emission-grpc.test.ts +3 -2
  306. package/src/scenarios/otel-emission.test.ts +6 -5
  307. package/src/scenarios/otel-trace-propagation-subworkflow.test.ts +7 -6
  308. package/src/scenarios/otel-trace-propagation.test.ts +2 -1
  309. package/src/scenarios/owner-subject-echo.test.ts +13 -12
  310. package/src/scenarios/owner-subject-shape.test.ts +11 -10
  311. package/src/scenarios/pack-manifest-extension-opacity.test.ts +8 -8
  312. package/src/scenarios/pack-registry-isolation.test.ts +4 -3
  313. package/src/scenarios/pack-registry-publish.test.ts +65 -63
  314. package/src/scenarios/pack-registry.test.ts +38 -36
  315. package/src/scenarios/pause-resume.test.ts +18 -16
  316. package/src/scenarios/policies.test.ts +20 -18
  317. package/src/scenarios/production-backpressure.test.ts +18 -16
  318. package/src/scenarios/production-retention-expiry.test.ts +8 -6
  319. package/src/scenarios/profile-discovery-core-alias.test.ts +13 -11
  320. package/src/scenarios/profileDerivation.test.ts +34 -33
  321. package/src/scenarios/prompt-all-four-kinds-events.test.ts +11 -9
  322. package/src/scenarios/prompt-composed-secret-redaction.test.ts +11 -9
  323. package/src/scenarios/prompt-composed-trust-marker.test.ts +10 -8
  324. package/src/scenarios/prompt-end-to-end-events.test.ts +17 -15
  325. package/src/scenarios/prompt-list-and-fetch.test.ts +16 -14
  326. package/src/scenarios/prompt-mutable-lifecycle.test.ts +13 -11
  327. package/src/scenarios/prompt-mutation-workspace-membership-enforced.test.ts +6 -4
  328. package/src/scenarios/prompt-pack-install.test.ts +14 -12
  329. package/src/scenarios/prompt-prefix-cache.test.ts +19 -17
  330. package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +11 -9
  331. package/src/scenarios/prompt-render-deterministic.test.ts +19 -17
  332. package/src/scenarios/prompt-resolution-chain-agent-intrinsic.test.ts +7 -5
  333. package/src/scenarios/prompt-resolution-chain-event.test.ts +12 -10
  334. package/src/scenarios/prompt-resolution-chain-fallback-cascade.test.ts +10 -8
  335. package/src/scenarios/prompt-resolution-chain-node-wins.test.ts +8 -6
  336. package/src/scenarios/prompt-template-shape.test.ts +30 -28
  337. package/src/scenarios/proposal-reviewable-learning.test.ts +19 -19
  338. package/src/scenarios/protocol-versions-array.test.ts +10 -9
  339. package/src/scenarios/provider-usage.test.ts +17 -15
  340. package/src/scenarios/providerPolicyEnforcement.test.ts +16 -14
  341. package/src/scenarios/purpose-propagation.test.ts +23 -21
  342. package/src/scenarios/queue-ack-nack-dlq.test.ts +12 -10
  343. package/src/scenarios/queue-cross-tenant-isolation.test.ts +8 -6
  344. package/src/scenarios/queue-publish-consume-roundtrip.test.ts +10 -8
  345. package/src/scenarios/rate-limit-envelope.test.ts +6 -5
  346. package/src/scenarios/redaction.test.ts +13 -11
  347. package/src/scenarios/redactionAdversarial.test.ts +11 -9
  348. package/src/scenarios/registry-public.test.ts +12 -11
  349. package/src/scenarios/replay-divergence-at-refusal.test.ts +16 -15
  350. package/src/scenarios/replay-fanout-suppression.test.ts +16 -15
  351. package/src/scenarios/replay-fork-arbitrary.test.ts +24 -23
  352. package/src/scenarios/replay-fork.test.ts +20 -19
  353. package/src/scenarios/replay-llm-cache-key-portable.test.ts +11 -9
  354. package/src/scenarios/replay-llm-cache-key.test.ts +22 -21
  355. package/src/scenarios/replay-observable-sequence-determinism.test.ts +4 -3
  356. package/src/scenarios/replay-retention-expiry.test.ts +11 -9
  357. package/src/scenarios/replay-side-effect-suppression.test.ts +21 -19
  358. package/src/scenarios/replayDeterminism.test.ts +13 -12
  359. package/src/scenarios/requirement-ledger.test.ts +15 -14
  360. package/src/scenarios/restart-during-run.test.ts +3 -2
  361. package/src/scenarios/route-coverage.test.ts +20 -19
  362. package/src/scenarios/run-diff.test.ts +22 -20
  363. package/src/scenarios/run-execution-bounds-shape.test.ts +14 -12
  364. package/src/scenarios/run-transport-economy.test.ts +13 -11
  365. package/src/scenarios/runner-ledger.test.ts +17 -16
  366. package/src/scenarios/runs-lifecycle.test.ts +7 -6
  367. package/src/scenarios/runtime-capabilities.test.ts +12 -10
  368. package/src/scenarios/runtime-requires-install-gate.test.ts +8 -8
  369. package/src/scenarios/runtime-requires-shape.test.ts +7 -6
  370. package/src/scenarios/safefetch-behavior.test.ts +22 -21
  371. package/src/scenarios/safefetch-live-audit.test.ts +14 -13
  372. package/src/scenarios/sandbox-memory-cap.test.ts +2 -1
  373. package/src/scenarios/sandbox-mvp-behavior.test.ts +24 -23
  374. package/src/scenarios/sandbox-no-host-fs-escape.test.ts +3 -2
  375. package/src/scenarios/sandbox-timeout-cap.test.ts +2 -1
  376. package/src/scenarios/sandbox-wasm-isolation.test.ts +14 -15
  377. package/src/scenarios/sandbox-wasm-timeout.test.ts +5 -6
  378. package/src/scenarios/scheduling-capability-shape.test.ts +8 -6
  379. package/src/scenarios/scheduling-cron-fires-once.test.ts +8 -6
  380. package/src/scenarios/search-bm25-roundtrip.test.ts +8 -6
  381. package/src/scenarios/secret-leakage-otel-attribute.test.ts +22 -20
  382. package/src/scenarios/self-hosted-runner.test.ts +26 -24
  383. package/src/scenarios/semantic-digest-vectors.test.ts +8 -7
  384. package/src/scenarios/speech-synthesis-roundtrip.test.ts +9 -7
  385. package/src/scenarios/speech-synthesis-unadvertised.test.ts +5 -3
  386. package/src/scenarios/sql-injection-rejection.test.ts +8 -6
  387. package/src/scenarios/sql-transaction-atomicity.test.ts +10 -8
  388. package/src/scenarios/staleClaim.test.ts +5 -4
  389. package/src/scenarios/stream-modes-buffer.test.ts +8 -7
  390. package/src/scenarios/stream-modes-mixed.test.ts +10 -9
  391. package/src/scenarios/stream-modes.test.ts +12 -11
  392. package/src/scenarios/stream-subscribe-from-beginning.test.ts +11 -9
  393. package/src/scenarios/stream-text-fixture.test.ts +14 -13
  394. package/src/scenarios/streamReconnect.test.ts +13 -11
  395. package/src/scenarios/strict-behavior-gate.test.ts +9 -8
  396. package/src/scenarios/subrun-approval-fail-closed.test.ts +2 -2
  397. package/src/scenarios/subrun-approval-gate.test.ts +3 -3
  398. package/src/scenarios/subrun-attestation-shape.test.ts +2 -2
  399. package/src/scenarios/subrun-checksum-stable.test.ts +4 -4
  400. package/src/scenarios/subworkflow-input-mapping.test.ts +16 -14
  401. package/src/scenarios/subworkflow.test.ts +10 -9
  402. package/src/scenarios/table-cross-tenant-isolation.test.ts +8 -6
  403. package/src/scenarios/table-cursor-pagination.test.ts +8 -6
  404. package/src/scenarios/table-schema-enforcement.test.ts +7 -5
  405. package/src/scenarios/test-seam-unauthenticated.test.ts +2 -2
  406. package/src/scenarios/tool-catalog-compact-projection.test.ts +10 -8
  407. package/src/scenarios/tool-catalog-projection.test.ts +11 -9
  408. package/src/scenarios/tool-descriptor-shape.test.ts +14 -15
  409. package/src/scenarios/tool-hooks-authorization-fail-closed.test.ts +3 -3
  410. package/src/scenarios/tool-hooks-content-free.test.ts +4 -4
  411. package/src/scenarios/tool-hooks-failure-honesty.test.ts +4 -4
  412. package/src/scenarios/tool-hooks-rate-limit.test.ts +2 -2
  413. package/src/scenarios/tool-hooks-secret-redaction.test.ts +2 -2
  414. package/src/scenarios/tool-hooks-shape.test.ts +3 -3
  415. package/src/scenarios/tool-session-lifecycle.test.ts +14 -13
  416. package/src/scenarios/trigger-bridge-delivery.test.ts +14 -14
  417. package/src/scenarios/trigger-bridge-shape.test.ts +19 -20
  418. package/src/scenarios/trigger-ingestion.test.ts +19 -17
  419. package/src/scenarios/trigger-stream-cdc-sources.test.ts +16 -14
  420. package/src/scenarios/vector-knn-roundtrip.test.ts +9 -7
  421. package/src/scenarios/verifier-gating.test.ts +8 -6
  422. package/src/scenarios/version-fold.test.ts +9 -8
  423. package/src/scenarios/version-negotiation.test.ts +12 -11
  424. package/src/scenarios/voice-bargein-no-partial-leak.test.ts +8 -6
  425. package/src/scenarios/voice-event-payloads-shape.test.ts +10 -11
  426. package/src/scenarios/voice-interim-not-durable.test.ts +7 -5
  427. package/src/scenarios/voice-streamref-tenant-bound.test.ts +5 -3
  428. package/src/scenarios/voice-synthesis-streaming.test.ts +11 -9
  429. package/src/scenarios/voice-transcription-streaming.test.ts +8 -6
  430. package/src/scenarios/voice-transcription-unadvertised.test.ts +5 -3
  431. package/src/scenarios/wasm-pack-abi-version-rejection.test.ts +3 -2
  432. package/src/scenarios/wasm-pack-invoke-completed.test.ts +3 -2
  433. package/src/scenarios/wasm-pack-invoke-suspended.test.ts +3 -2
  434. package/src/scenarios/wasm-pack-load.test.ts +4 -3
  435. package/src/scenarios/wasm-pack-memory-cap.test.ts +5 -4
  436. package/src/scenarios/wasm-pack-replay-determinism.test.ts +2 -1
  437. package/src/scenarios/webhook-negative.test.ts +11 -9
  438. package/src/scenarios/webhook-receiver-adversarial.test.ts +8 -7
  439. package/src/scenarios/webhook-sig-algorithm.test.ts +5 -3
  440. package/src/scenarios/webhook-signed-delivery.test.ts +16 -15
  441. package/src/scenarios/webhook-tenant-isolation.test.ts +16 -14
  442. package/src/scenarios/workflow-chain-deferred-parameters.test.ts +28 -30
  443. package/src/scenarios/workflow-chain-expansion.test.ts +21 -20
  444. package/src/scenarios/workflow-chain-host-expansion.test.ts +21 -20
  445. package/src/scenarios/workflow-chain-pack-manifest-validation.test.ts +14 -12
  446. package/src/scenarios/workflow-chain-pack-signature-verification.test.ts +5 -4
  447. package/src/scenarios/workflow-chain-unresolvable-typeid.test.ts +9 -8
  448. package/src/scenarios/workflow-primary-output-annotation.test.ts +7 -6
  449. package/src/scenarios/workflow-variable-format.test.ts +24 -24
  450. package/src/scenarios/workload-identity-behavior.test.ts +15 -13
  451. package/src/scenarios/workload-identity-chain-bounds.test.ts +18 -17
  452. package/src/scenarios/workspace-behavior.test.ts +19 -18
  453. package/src/scenarios/workspace-capability-shape.test.ts +3 -2
  454. package/src/scenarios/workspace-cross-tenant-isolation-blackbox.test.ts +6 -5
  455. package/src/scenarios/workspace-cross-tenant-isolation.test.ts +7 -6
  456. package/src/scenarios/x-openwop-form-pack-manifest.test.ts +8 -7
  457. package/src/setup.ts +4 -2
  458. package/vitest.config.ts +5 -1
  459. package/api/.redocly.lint-ignore.yaml +0 -22
  460. package/api/asyncapi.yaml +0 -834
  461. package/api/grpc/openwop.proto +0 -251
  462. package/api/openapi.yaml +0 -2693
  463. package/api/redocly.yaml +0 -23
  464. package/schemas/README.md +0 -144
  465. package/schemas/a2a-task-state.schema.json +0 -78
  466. package/schemas/a2ui-surface-delta-frame.schema.json +0 -48
  467. package/schemas/agent-deployment-transition.schema.json +0 -49
  468. package/schemas/agent-deployment.schema.json +0 -54
  469. package/schemas/agent-eval-suite.schema.json +0 -140
  470. package/schemas/agent-inventory-response.schema.json +0 -115
  471. package/schemas/agent-manifest.schema.json +0 -156
  472. package/schemas/agent-org-chart.schema.json +0 -82
  473. package/schemas/agent-ref.schema.json +0 -63
  474. package/schemas/agent-roster-entry.schema.json +0 -81
  475. package/schemas/agent-roster-response.schema.json +0 -21
  476. package/schemas/ai-envelope.schema.json +0 -134
  477. package/schemas/annotation-create.schema.json +0 -37
  478. package/schemas/annotation.schema.json +0 -56
  479. package/schemas/artifact-type-pack-manifest.schema.json +0 -244
  480. package/schemas/audit-verify-result.schema.json +0 -90
  481. package/schemas/budget-policy.schema.json +0 -18
  482. package/schemas/capabilities.schema.json +0 -4124
  483. package/schemas/certification-bundle-v2.schema.json +0 -118
  484. package/schemas/channel-presence-payload.schema.json +0 -41
  485. package/schemas/channel-written-payload.schema.json +0 -55
  486. package/schemas/chat-card-pack-manifest.schema.json +0 -253
  487. package/schemas/compact-tool-descriptor.schema.json +0 -51
  488. package/schemas/compensation-policy.schema.json +0 -64
  489. package/schemas/conformance-certification-bundle.schema.json +0 -86
  490. package/schemas/connection-pack-manifest.schema.json +0 -353
  491. package/schemas/conversation-event.schema.json +0 -168
  492. package/schemas/conversation-turn.schema.json +0 -117
  493. package/schemas/core-conformance-mock-agent-config.schema.json +0 -152
  494. package/schemas/credential-provenance.schema.json +0 -18
  495. package/schemas/credential-reference.schema.json +0 -21
  496. package/schemas/debug-bundle.schema.json +0 -196
  497. package/schemas/dispatch-config.schema.json +0 -112
  498. package/schemas/envelopes/clarification.request.schema.json +0 -52
  499. package/schemas/envelopes/error.schema.json +0 -30
  500. package/schemas/envelopes/media.audio.schema.json +0 -38
  501. package/schemas/envelopes/media.file.schema.json +0 -37
  502. package/schemas/envelopes/media.image.schema.json +0 -33
  503. package/schemas/envelopes/schema.request.schema.json +0 -26
  504. package/schemas/envelopes/schema.response.schema.json +0 -22
  505. package/schemas/envelopes/ui.a2ui-surface.schema.json +0 -154
  506. package/schemas/error-envelope.schema.json +0 -25
  507. package/schemas/eval-summary.schema.json +0 -92
  508. package/schemas/export-bundle.schema.json +0 -66
  509. package/schemas/form-content-pack-manifest.schema.json +0 -243
  510. package/schemas/frontend-plugin-manifest.schema.json +0 -109
  511. package/schemas/goal.schema.json +0 -104
  512. package/schemas/heartbeat-evaluated.schema.json +0 -14
  513. package/schemas/heartbeat-state-changed.schema.json +0 -14
  514. package/schemas/localized-content-language-settings.schema.json +0 -26
  515. package/schemas/localized-content-page-response.schema.json +0 -60
  516. package/schemas/localized-content-page.schema.json +0 -62
  517. package/schemas/localized-content-section.schema.json +0 -51
  518. package/schemas/memory-entry.schema.json +0 -36
  519. package/schemas/memory-list-options.schema.json +0 -37
  520. package/schemas/node-pack-manifest.schema.json +0 -654
  521. package/schemas/orchestrator-decision.schema.json +0 -90
  522. package/schemas/org-chart-responsibility-view.schema.json +0 -26
  523. package/schemas/pack-lockfile.schema.json +0 -108
  524. package/schemas/prompt-kind.schema.json +0 -8
  525. package/schemas/prompt-pack-manifest.schema.json +0 -117
  526. package/schemas/prompt-ref.schema.json +0 -40
  527. package/schemas/prompt-template.schema.json +0 -149
  528. package/schemas/proposal.schema.json +0 -84
  529. package/schemas/registry-version-manifest.schema.json +0 -208
  530. package/schemas/residency.schema.json +0 -16
  531. package/schemas/run-ancestry-response.schema.json +0 -54
  532. package/schemas/run-diff-response.schema.json +0 -64
  533. package/schemas/run-event-payloads.schema.json +0 -4452
  534. package/schemas/run-event.schema.json +0 -211
  535. package/schemas/run-options.schema.json +0 -80
  536. package/schemas/run-orchestrator-decided-event.schema.json +0 -20
  537. package/schemas/run-snapshot.schema.json +0 -148
  538. package/schemas/security-advisory.schema.json +0 -109
  539. package/schemas/self-hosted-runner-dispatch-frame.schema.json +0 -79
  540. package/schemas/self-hosted-runner-registration.schema.json +0 -53
  541. package/schemas/self-hosted-runner-result-frame.schema.json +0 -38
  542. package/schemas/subject.schema.json +0 -56
  543. package/schemas/suspend-request.schema.json +0 -207
  544. package/schemas/tool-descriptor.schema.json +0 -63
  545. package/schemas/trigger-event.schema.json +0 -222
  546. package/schemas/trigger-subscription-registration.schema.json +0 -67
  547. package/schemas/trigger-subscription.schema.json +0 -26
  548. package/schemas/ui-plugin-message.schema.json +0 -90
  549. package/schemas/workflow-chain-pack-manifest.schema.json +0 -615
  550. package/schemas/workflow-definition.schema.json +0 -850
  551. package/schemas/workload-identity.schema.json +0 -79
  552. package/schemas/workspace-file-create.schema.json +0 -20
  553. package/schemas/workspace-file.schema.json +0 -39
@@ -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
  });
@@ -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
  describe('agent-live-structured-output (RFC 0077 §B step 6)', () => {
29
30
  it('fails the invocation on a result that violates handoff.returnSchemaRef', async () => {
@@ -32,25 +33,25 @@ describe('agent-live-structured-output (RFC 0077 §B step 6)', () => {
32
33
  const advertised = cap?.supported === true && cap?.structuredOutput === true;
33
34
  if (!behaviorGate('openwop-live-structured-output', advertised)) 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({
37
38
  source: 'run-api',
38
39
  returnSchemaRef: 'conformance-strict-handoff',
39
40
  forceInvalidResult: true,
40
41
  });
41
- if (res === null || !res.runId) return; // seam/hook absent — soft-skip
42
+ 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
42
43
 
43
44
  const q = await queryTestEvents(res.runId, { type: 'agent.invocation.completed' });
44
- if (!q.ok || !q.events[0]) return;
45
+ if (!q.ok || !q.events[0]) return softSkip('blocked', 'precondition not met — `!q.ok || !q.events[0]` returned early (seam, prior step, or fixture unavailable)');
45
46
  const payload = q.events[q.events.length - 1]!.payload;
46
47
 
47
48
  expect(
48
49
  payload.outcome === 'failed',
49
- driver.describe('RFC 0077 §B step 6', 'a result violating handoff.returnSchemaRef MUST fail the invocation (outcome "failed"), not ship as completed'),
50
+ req('openwop.it.agent-live-structured-output.fails-the-invocation-on-a-result-that-violates-handoff-returnschemaref', 'RFC 0077 §B step 6', 'a result violating handoff.returnSchemaRef MUST fail the invocation (outcome "failed"), not ship as completed'),
50
51
  ).toBe(true);
51
52
  expect(
52
53
  payload.schemaValidated !== true,
53
- driver.describe('RFC 0077 §B step 6', 'schemaValidated MUST NOT be true for a schema-violating result'),
54
+ req('openwop.it.agent-live-structured-output.fails-the-invocation-on-a-result-that-violates-handoff-returnschemaref', 'RFC 0077 §B step 6', 'schemaValidated MUST NOT be true for a schema-violating result'),
54
55
  ).toBe(true);
55
56
 
56
57
  await resetTestSeam();
@@ -11,8 +11,8 @@
11
11
 
12
12
  import { describe, it, expect } from 'vitest';
13
13
  import { softSkip } from '../lib/soft-skip.js';
14
- import { driver } from '../lib/driver.js';
15
14
  import { readExecutionModelCap, isVersion5, invokeAgentLoop } from '../lib/agentLoop.js';
15
+ import { req } from '../lib/requirement-ids.js';
16
16
 
17
17
  describe('agent-loop-iteration-monotonic (RFC 0061 §B)', () => {
18
18
  it('iteration increments by exactly 1 per orchestrator turn, 1-based', async () => {
@@ -22,13 +22,13 @@ describe('agent-loop-iteration-monotonic (RFC 0061 §B)', () => {
22
22
  const decisions = res.decisions ?? [];
23
23
  expect(
24
24
  decisions.length >= 1,
25
- driver.describe('RFC 0061 §B', 'a multi-turn loop MUST emit one runOrchestrator.decided per turn'),
25
+ req('openwop.it.agent-loop-iteration-monotonic.iteration-increments-by-exactly-1-per-orchestrator-turn-1-based', 'RFC 0061 §B', 'a multi-turn loop MUST emit one runOrchestrator.decided per turn'),
26
26
  ).toBe(true);
27
27
  const iterations = decisions.map((d) => d.iteration);
28
28
  const expected = decisions.map((_, k) => k + 1);
29
29
  expect(
30
30
  JSON.stringify(iterations),
31
- driver.describe('RFC 0061 §B', 'iteration MUST be 1-based + monotonic, incrementing by exactly 1 per turn'),
31
+ req('openwop.it.agent-loop-iteration-monotonic.iteration-increments-by-exactly-1-per-orchestrator-turn-1-based', 'RFC 0061 §B', 'iteration MUST be 1-based + monotonic, incrementing by exactly 1 per turn'),
32
32
  ).toBe(JSON.stringify(expected));
33
33
  });
34
34
  });
@@ -11,8 +11,8 @@
11
11
 
12
12
  import { describe, it, expect } from 'vitest';
13
13
  import { softSkip } from '../lib/soft-skip.js';
14
- import { driver } from '../lib/driver.js';
15
14
  import { readExecutionModelCap, invokeAgentLoop } from '../lib/agentLoop.js';
15
+ import { req } from '../lib/requirement-ids.js';
16
16
 
17
17
  describe('agent-loop-stateful-resume (RFC 0061 §D)', () => {
18
18
  it('a mid-loop suspend resumes at the same iteration, counter intact', async () => {
@@ -23,7 +23,7 @@ describe('agent-loop-stateful-resume (RFC 0061 §D)', () => {
23
23
  if (res === null) return softSkip('blocked', 'seam absent — soft-skip');
24
24
  expect(
25
25
  res.resumedIteration,
26
- driver.describe('RFC 0061 §D', 'a stateful resume MUST continue at the suspend iteration — the counter does not reset or skip'),
26
+ req('openwop.it.agent-loop-stateful-resume.a-mid-loop-suspend-resumes-at-the-same-iteration-counter-intact', 'RFC 0061 §D', 'a stateful resume MUST continue at the suspend iteration — the counter does not reset or skip'),
27
27
  ).toBe(2);
28
28
  });
29
29
  });
@@ -13,9 +13,9 @@
13
13
 
14
14
  import { describe, it, expect } from 'vitest';
15
15
  import { softSkip } from '../lib/soft-skip.js';
16
- import { driver } from '../lib/driver.js';
17
16
  import { executionModelVersionMax } from '../lib/execution-model-version.js';
18
17
  import { readExecutionModelCap } from '../lib/agentLoop.js';
18
+ import { req } from '../lib/requirement-ids.js';
19
19
 
20
20
  describe('agent-loop-version5-shape: advertisement (RFC 0061 §A)', () => {
21
21
  it('executionModel.statefulResume/transcriptWindow are well-formed when present', async () => {
@@ -24,13 +24,13 @@ describe('agent-loop-version5-shape: advertisement (RFC 0061 §A)', () => {
24
24
  if (em.statefulResume !== undefined) {
25
25
  expect(
26
26
  typeof em.statefulResume,
27
- driver.describe('capabilities.schema.json §multiAgent.executionModel', 'statefulResume MUST be a boolean when present'),
27
+ req('openwop.it.agent-loop-version5-shape.executionmodel-statefulresume-transcriptwindow-are-well-formed-when-present', 'capabilities.schema.json §multiAgent.executionModel', 'statefulResume MUST be a boolean when present'),
28
28
  ).toBe('boolean');
29
29
  }
30
30
  if (em.transcriptWindow !== undefined) {
31
31
  expect(
32
32
  typeof em.transcriptWindow === 'number' && (em.transcriptWindow as number) >= 1,
33
- driver.describe('capabilities.schema.json §multiAgent.executionModel', 'transcriptWindow MUST be a positive integer when present'),
33
+ req('openwop.it.agent-loop-version5-shape.executionmodel-statefulresume-transcriptwindow-are-well-formed-when-present', 'capabilities.schema.json §multiAgent.executionModel', 'transcriptWindow MUST be a positive integer when present'),
34
34
  ).toBe(true);
35
35
  }
36
36
  if (typeof em.version === 'number') {
@@ -40,7 +40,7 @@ describe('agent-loop-version5-shape: advertisement (RFC 0061 §A)', () => {
40
40
  const max = executionModelVersionMax();
41
41
  expect(
42
42
  (em.version as number) >= 1 && (em.version as number) <= max,
43
- driver.describe('capabilities.schema.json §multiAgent.executionModel', `version MUST be within the 1–${max} ladder (schema maximum)`),
43
+ req('openwop.it.agent-loop-version5-shape.executionmodel-statefulresume-transcriptwindow-are-well-formed-when-present', 'capabilities.schema.json §multiAgent.executionModel', `version MUST be within the 1–${max} ladder (schema maximum)`),
44
44
  ).toBe(true);
45
45
  }
46
46
  });
@@ -12,8 +12,8 @@
12
12
 
13
13
  import { describe, it, expect } from 'vitest';
14
14
  import { softSkip } from '../lib/soft-skip.js';
15
- import { driver } from '../lib/driver.js';
16
15
  import { readExecutionModelCap, isVersion5, hasWorkspace, invokeAgentLoop } from '../lib/agentLoop.js';
16
+ import { req } from '../lib/requirement-ids.js';
17
17
 
18
18
  describe('agent-loop-workspace-snapshot (RFC 0061 §C)', () => {
19
19
  it('a turn-i workspace write is invisible to turn i, visible to turn i+1', async () => {
@@ -24,11 +24,11 @@ describe('agent-loop-workspace-snapshot (RFC 0061 §C)', () => {
24
24
  const vis = res.workspaceVisible ?? {};
25
25
  expect(
26
26
  vis.atWriteTurn,
27
- driver.describe('RFC 0061 §C', 'a workspace write during turn i MUST be invisible to turn i\'s snapshot'),
27
+ req('openwop.it.agent-loop-workspace-snapshot.a-turn-i-workspace-write-is-invisible-to-turn-i-visible-to-turn-i-1', 'RFC 0061 §C', 'a workspace write during turn i MUST be invisible to turn i\'s snapshot'),
28
28
  ).toBe(false);
29
29
  expect(
30
30
  vis.atNextTurn,
31
- driver.describe('RFC 0061 §C', 'a workspace write during turn i MUST be visible to turn i+1'),
31
+ req('openwop.it.agent-loop-workspace-snapshot.a-turn-i-workspace-write-is-invisible-to-turn-i-visible-to-turn-i-1', 'RFC 0061 §C', 'a workspace write during turn i MUST be visible to turn i+1'),
32
32
  ).toBe(true);
33
33
  });
34
34
  });
@@ -34,9 +34,9 @@ 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
+ import { req } from '../lib/requirement-ids.js';
37
38
 
38
39
  const BASE = 'https://openwop.dev/spec/v1/';
39
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
40
40
  function loadSchema(name: string): Record<string, unknown> {
41
41
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
42
42
  }
@@ -61,56 +61,56 @@ describe('agent-manifest-role-profile: AgentManifest.role + Skill profile (RFC 0
61
61
  it('NO role + any memoryShape (conversation+longTerm) validates — explicit, never inferred', () => {
62
62
  expect(
63
63
  manifest({ ...base, memoryShape: { scratchpad: true, conversation: true, longTerm: true } }),
64
- why('RFC 0131 §A', 'absent role ⇒ unconstrained; nothing reclassifies (today’s meaning, unchanged)'),
64
+ req('openwop.it.agent-manifest-role-profile.no-role-any-memoryshape-conversation-longterm-validates-explicit-never-inferred', 'RFC 0131 §A', 'absent role ⇒ unconstrained; nothing reclassifies (today’s meaning, unchanged)'),
65
65
  ).toBe(true);
66
66
  });
67
67
 
68
68
  it('NO role + handoff + rich memory validates — handoff presence does NOT imply skill', () => {
69
69
  expect(
70
70
  manifest({ ...base, handoff, memoryShape: { conversation: true, longTerm: true } }),
71
- why('RFC 0131 §A / Motivation 2', 'handoff is an interop contract, orthogonal to role — no inference'),
71
+ req('openwop.it.agent-manifest-role-profile.no-role-handoff-rich-memory-validates-handoff-presence-does-not-imply-skill', 'RFC 0131 §A / Motivation 2', 'handoff is an interop contract, orthogonal to role — no inference'),
72
72
  ).toBe(true);
73
73
  });
74
74
 
75
75
  it('role:"skill" WITH handoff + scratchpad-only memory validates', () => {
76
76
  expect(
77
77
  manifest({ ...base, role: 'skill', handoff, memoryShape: { scratchpad: true, conversation: false, longTerm: false } }),
78
- why('RFC 0131 §B', 'a well-formed skill (handoff + scratchpad-only) MUST validate'),
78
+ req('openwop.it.agent-manifest-role-profile.role-skill-with-handoff-scratchpad-only-memory-validates', 'RFC 0131 §B', 'a well-formed skill (handoff + scratchpad-only) MUST validate'),
79
79
  ).toBe(true);
80
80
  });
81
81
 
82
82
  it('role:"skill" with memoryShape.longTerm:true FAILS validation (malformed, not degraded)', () => {
83
83
  expect(
84
84
  manifest({ ...base, role: 'skill', handoff, memoryShape: { scratchpad: true, longTerm: true } }),
85
- why('RFC 0131 §B', 'a skill declaring longTerm memory is malformed — reject at publish/install'),
85
+ req('openwop.it.agent-manifest-role-profile.role-skill-with-memoryshape-longterm-true-fails-validation-malformed-not-degrade', 'RFC 0131 §B', 'a skill declaring longTerm memory is malformed — reject at publish/install'),
86
86
  ).toBe(false);
87
87
  });
88
88
 
89
89
  it('role:"skill" with memoryShape.conversation:true FAILS validation', () => {
90
90
  expect(
91
91
  manifest({ ...base, role: 'skill', handoff, memoryShape: { conversation: true } }),
92
- why('RFC 0131 §B', 'a skill declaring conversation memory is malformed — reject'),
92
+ req('openwop.it.agent-manifest-role-profile.role-skill-with-memoryshape-conversation-true-fails-validation', 'RFC 0131 §B', 'a skill declaring conversation memory is malformed — reject'),
93
93
  ).toBe(false);
94
94
  });
95
95
 
96
96
  it('role:"skill" MISSING handoff FAILS validation', () => {
97
97
  expect(
98
98
  manifest({ ...base, role: 'skill', memoryShape: { scratchpad: true } }),
99
- why('RFC 0131 §B', 'a skill MUST declare handoff (task→return capability)'),
99
+ req('openwop.it.agent-manifest-role-profile.role-skill-missing-handoff-fails-validation', 'RFC 0131 §B', 'a skill MUST declare handoff (task→return capability)'),
100
100
  ).toBe(false);
101
101
  });
102
102
 
103
103
  it('role:"assistant" with conversation+longTerm (and handoff) validates — no profile binds it', () => {
104
104
  expect(
105
105
  manifest({ ...base, role: 'assistant', handoff, memoryShape: { scratchpad: true, conversation: true, longTerm: true } }),
106
- why('RFC 0131 §A', 'an assistant’s conversation + long-term memory are legitimate; it MAY ship handoff'),
106
+ req('openwop.it.agent-manifest-role-profile.role-assistant-with-conversation-longterm-and-handoff-validates-no-profile-binds', 'RFC 0131 §A', 'an assistant’s conversation + long-term memory are legitimate; it MAY ship handoff'),
107
107
  ).toBe(true);
108
108
  });
109
109
 
110
110
  it('role outside the ["skill","assistant"] enum FAILS', () => {
111
111
  expect(
112
112
  manifest({ ...base, role: 'agent' }),
113
- why('RFC 0131 §A', '"agent" is not an enum value (it is the overloaded word the RFC removes)'),
113
+ req('openwop.it.agent-manifest-role-profile.role-outside-the-skill-assistant-enum-fails', 'RFC 0131 §A', '"agent" is not an enum value (it is the overloaded word the RFC removes)'),
114
114
  ).toBe(false);
115
115
  });
116
116
  });