@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
@@ -23,6 +23,7 @@ import { describe, it, expect } from 'vitest';
23
23
  import { softSkip } from '../lib/soft-skip.js';
24
24
  import { driver } from '../lib/driver.js';
25
25
  import { capabilityFamily, discoveryFamilies } from '../lib/discovery-capabilities.js';
26
+ import { req } from '../lib/requirement-ids.js';
26
27
 
27
28
  async function isMcpClientSupported(): Promise<boolean> {
28
29
  const disco = await driver.get('/.well-known/openwop');
@@ -44,12 +45,12 @@ describe('mcp-toolcall-redaction: capability advertisement contract', () => {
44
45
  };
45
46
  }), 'mcpClient');
46
47
 
47
- expect(cap?.supported, driver.describe(
48
+ expect(cap?.supported, req('openwop.it.mcp-toolcall-redaction.host-advertising-mcpclient-must-declare-trustboundary-untrusted',
48
49
  'host-capabilities.md §host.mcp',
49
50
  'mcpClient.supported MUST be a boolean',
50
51
  )).toBe(true);
51
52
 
52
- expect(Array.isArray(cap?.transports), driver.describe(
53
+ expect(Array.isArray(cap?.transports), req('openwop.it.mcp-toolcall-redaction.host-advertising-mcpclient-must-declare-trustboundary-untrusted',
53
54
  'host-capabilities.md §host.mcp',
54
55
  'mcpClient.transports MUST be an array of transport identifiers',
55
56
  )).toBe(true);
@@ -59,7 +60,7 @@ describe('mcp-toolcall-redaction: capability advertisement contract', () => {
59
60
  // Hosts advertising mcpClient MUST encode the boundary in the
60
61
  // capability so downstream consumers (LLM nodes) treat the
61
62
  // content accordingly.
62
- expect(cap?.trustBoundary, driver.describe(
63
+ expect(cap?.trustBoundary, req('openwop.it.mcp-toolcall-redaction.host-advertising-mcpclient-must-declare-trustboundary-untrusted',
63
64
  'SECURITY/threat-model-prompt-injection.md §"UNTRUSTED marker"',
64
65
  'mcpClient.trustBoundary MUST be "untrusted" — downstream LLM nodes treat tool content as user data',
65
66
  )).toBe('untrusted');
@@ -27,10 +27,11 @@
27
27
  import { describe, it, expect } from 'vitest';
28
28
  import { driver } from '../lib/driver.js';
29
29
  import { readErrorCode } from '../lib/error-envelope.js';
30
- import { seamAbsent } from '../lib/soft-skip.js';
30
+ import { seamAbsent, softSkip } from '../lib/soft-skip.js';
31
31
  import { behaviorGate } from '../lib/behavior-gate.js';
32
32
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
33
33
  import { getMcpFakeServer } from '../lib/mcp-fake-server.js';
34
+ import { req } from '../lib/requirement-ids.js';
34
35
 
35
36
  /**
36
37
  * Callback-shaped: the host issues MCP calls to the suite's fake server, which records the revision header.
@@ -67,7 +68,7 @@ describe('RFC 0153 §A/§B — MCP revision negotiation', () => {
67
68
  for (const v of caps?.protocolVersions ?? []) {
68
69
  expect(
69
70
  DATE_FORM.test(v),
70
- driver.describe(
71
+ req('openwop.it.mcp-version-negotiation.advertised-revisions-use-mcp-date-form-and-include-the-preferred-one',
71
72
  'RFCS/0153-mcp-2026-07-28-versioned-composition.md §A',
72
73
  `'${v}' is not MCP's date form. MCP revisions ARE dates, and 'latest' or an unpadded ` +
73
74
  'month lets two hosts disagree about which revision they share while both look valid.',
@@ -76,39 +77,39 @@ describe('RFC 0153 §A/§B — MCP revision negotiation', () => {
76
77
  }
77
78
  expect(
78
79
  caps?.protocolVersions ?? [],
79
- driver.describe('RFCS/0153 §A', '`preferredVersion` MUST be one the host actually lists'),
80
+ req('openwop.it.mcp-version-negotiation.advertised-revisions-use-mcp-date-form-and-include-the-preferred-one', 'RFCS/0153 §A', '`preferredVersion` MUST be one the host actually lists'),
80
81
  ).toContain(caps?.preferredVersion);
81
82
  });
82
83
 
83
84
  it('outbound calls carry MCP-Protocol-Version in date form', async () => {
84
85
  if (!behaviorGate(PROFILE, await negotiationAdvertised())) return;
85
86
  const server = getMcpFakeServer();
86
- if (server === null) return;
87
+ if (server === null) return softSkip('blocked', 'precondition not met — `server === null` returned early (seam, prior step, or fixture unavailable)');
87
88
  server.reset();
88
89
  const drive = await driver.post('/v1/host/sample/mcp/invoke', { serverUrl: server.endpoint() });
89
90
  if (drive.status === 404 || drive.status === 403) {
90
91
  expect(
91
92
  drive.status,
92
- driver.describe(
93
+ req('openwop.it.mcp-version-negotiation.outbound-calls-carry-mcp-protocol-version-in-date-form',
93
94
  'RFCS/0153 §B',
94
95
  'a host advertising MCP revisions MUST expose an invoke seam so the negotiated revision ' +
95
96
  'is observable. Without it the requirement resolves to `blocked` per RFC 0148 §A — not ' +
96
97
  'to a pass.',
97
98
  ),
98
99
  ).not.toBe(404);
99
- return;
100
+ return softSkip('blocked', 'precondition not met — `drive.status === 404 || drive.status === 403` returned early (seam, prior step, or fixture unavailable)');
100
101
  }
101
102
  const calls = server.invocations();
102
- expect(calls.length, 'the host MUST have called the server').toBeGreaterThan(0);
103
+ expect(calls.length, req('openwop.it.mcp-version-negotiation.outbound-calls-carry-mcp-protocol-version-in-date-form', 'RFCS/0153 §B', 'the host MUST have called the server')).toBeGreaterThan(0);
103
104
  for (const c of calls) {
104
105
  const v = c.headers['mcp-protocol-version'];
105
106
  expect(
106
107
  v,
107
- driver.describe('RFCS/0153 §A', 'every MCP call MUST declare its revision'),
108
+ req('openwop.it.mcp-version-negotiation.outbound-calls-carry-mcp-protocol-version-in-date-form', 'RFCS/0153 §A', 'every MCP call MUST declare its revision'),
108
109
  ).toBeTruthy();
109
110
  expect(
110
111
  DATE_FORM.test(v ?? ''),
111
- driver.describe(
112
+ req('openwop.it.mcp-version-negotiation.outbound-calls-carry-mcp-protocol-version-in-date-form',
112
113
  'RFCS/0153 §A',
113
114
  `the revision on the wire MUST be MCP's date form; got '${v}'. A malformed revision is ` +
114
115
  'unmatchable against a pinned peer, and the failure then surfaces at the peer rather ' +
@@ -121,7 +122,7 @@ describe('RFC 0153 §A/§B — MCP revision negotiation', () => {
121
122
  it('the negotiated revision is one the host advertises', async () => {
122
123
  if (!behaviorGate(PROFILE, await negotiationAdvertised())) return;
123
124
  const server = getMcpFakeServer();
124
- if (server === null) return;
125
+ if (server === null) return softSkip('blocked', 'precondition not met — `server === null` returned early (seam, prior step, or fixture unavailable)');
125
126
  const caps = await mcp();
126
127
  server.reset();
127
128
  const drive = await driver.post('/v1/host/sample/mcp/invoke', { serverUrl: server.endpoint() });
@@ -132,7 +133,7 @@ describe('RFC 0153 §A/§B — MCP revision negotiation', () => {
132
133
  for (const c of server.invocations()) {
133
134
  expect(
134
135
  caps?.protocolVersions ?? [],
135
- driver.describe(
136
+ req('openwop.it.mcp-version-negotiation.the-negotiated-revision-is-one-the-host-advertises',
136
137
  'RFCS/0153 §A/§B',
137
138
  'the revision sent on the wire MUST appear in `protocolVersions`. Negotiating an ' +
138
139
  'unadvertised revision makes the discovery document unreliable for every consumer ' +
@@ -145,7 +146,7 @@ describe('RFC 0153 §A/§B — MCP revision negotiation', () => {
145
146
  it('an unsupported revision fails through the canonical interop envelope', async () => {
146
147
  if (!behaviorGate(PROFILE, await negotiationAdvertised())) return;
147
148
  const server = getMcpFakeServer();
148
- if (server === null) return;
149
+ if (server === null) return softSkip('blocked', 'precondition not met — `server === null` returned early (seam, prior step, or fixture unavailable)');
149
150
  const drive = await driver.post('/v1/host/sample/mcp/invoke', {
150
151
  serverUrl: server.endpoint(),
151
152
  requestVersion: '1999-01-01',
@@ -153,13 +154,13 @@ describe('RFC 0153 §A/§B — MCP revision negotiation', () => {
153
154
  if (drive.status === 404 || drive.status === 403) return seamAbsent(`host advertises mcp version negotiation but the invoke seam /v1/host/sample/mcp/invoke answered ${drive.status} — the host-as-client legs are unobservable (host-sample-test-seams.md)`);
154
155
  expect(
155
156
  drive.status >= 400,
156
- driver.describe('RFCS/0153 §B', 'an unsupported revision MUST fail rather than silently proceed'),
157
+ req('openwop.it.mcp-version-negotiation.an-unsupported-revision-fails-through-the-canonical-interop-envelope', 'RFCS/0153 §B', 'an unsupported revision MUST fail rather than silently proceed'),
157
158
  ).toBe(true);
158
159
  // S28: canonical envelope is FLAT (`error: "<code>"`, error-envelope.schema.json);
159
160
  // the nested `error.code` is tolerated by the lib only through the deprecation window.
160
161
  expect(
161
162
  readErrorCode(drive.json),
162
- driver.describe(
163
+ req('openwop.it.mcp-version-negotiation.an-unsupported-revision-fails-through-the-canonical-interop-envelope',
163
164
  'RFCS/0153 §B',
164
165
  'the upstream error MUST be projected through the canonical OpenWOP interop envelope — a ' +
165
166
  'raw JSON-RPC error body leaves the caller parsing a foreign protocol to learn its own ' +
@@ -33,6 +33,8 @@ import { join } from 'node:path';
33
33
  import { driver } from '../lib/driver.js';
34
34
  import { SCHEMAS_DIR } from '../lib/paths.js';
35
35
  import { capabilityFamily, discoveryFamilies } from '../lib/discovery-capabilities.js';
36
+ import { req } from '../lib/requirement-ids.js';
37
+ import { softSkip } from '../lib/soft-skip.js';
36
38
 
37
39
  const MEDIA_KINDS = ['media.image', 'media.audio', 'media.file'] as const;
38
40
  const HTTP_SKIP = !process.env.OPENWOP_BASE_URL;
@@ -51,7 +53,7 @@ describe('media-url-inline-cap: media payload schemas compile + round-trip (RFC
51
53
  it(`envelopes/${kind}.schema.json compiles under Ajv2020`, () => {
52
54
  expect(
53
55
  compile(kind),
54
- `ai-envelope.md §"Media reference payloads": ${kind} payload schema MUST compile`,
56
+ req('openwop.it.media-url-inline-cap.envelopes-schema-json-compiles-under-ajv2020', 'RFC 0055 §C', `ai-envelope.md §"Media reference payloads": ${kind} payload schema MUST compile`),
55
57
  ).toBeTypeOf('function');
56
58
  });
57
59
  }
@@ -62,22 +64,22 @@ describe('media-url-inline-cap: media payload schemas compile + round-trip (RFC
62
64
  bytes: 184320,
63
65
  mimeType: 'image/png',
64
66
  });
65
- expect(ok, 'URL-reference media payload MUST validate').toBe(true);
67
+ expect(ok, req('openwop.it.media-url-inline-cap.accepts-a-url-reference-image-payload', 'RFC 0055 §C', 'URL-reference media payload MUST validate')).toBe(true);
66
68
  });
67
69
 
68
70
  it('accepts an inline-base64 audio payload', () => {
69
71
  const ok = compile('media.audio')({ base64: 'AAAA', bytes: 3, mimeType: 'audio/ogg', durationSeconds: 1.2 });
70
- expect(ok, 'inline-base64 media payload MUST validate').toBe(true);
72
+ expect(ok, req('openwop.it.media-url-inline-cap.accepts-an-inline-base64-audio-payload', 'RFC 0055 §C', 'inline-base64 media payload MUST validate')).toBe(true);
71
73
  });
72
74
 
73
75
  it('rejects a payload missing required bytes', () => {
74
76
  const ok = compile('media.file')({ url: 'https://host.example/v1/runs/run_1/assets/report.pdf' });
75
- expect(ok, 'ai-envelope.md §"Media reference payloads": `bytes` is required').toBe(false);
77
+ expect(ok, req('openwop.it.media-url-inline-cap.rejects-a-payload-missing-required-bytes', 'RFC 0055 §C', 'ai-envelope.md §"Media reference payloads": `bytes` is required')).toBe(false);
76
78
  });
77
79
 
78
80
  it('rejects an unknown property (additionalProperties:false)', () => {
79
81
  const ok = compile('media.image')({ bytes: 1, wat: true });
80
- expect(ok, 'media payload is additionalProperties:false').toBe(false);
82
+ expect(ok, req('openwop.it.media-url-inline-cap.rejects-an-unknown-property-additionalproperties-false', 'RFC 0055 §C', 'media payload is additionalProperties:false')).toBe(false);
81
83
  });
82
84
  });
83
85
 
@@ -88,12 +90,12 @@ interface DiscoveryDoc {
88
90
  describe.skipIf(HTTP_SKIP)('media-url-inline-cap: advertisement shape (RFC 0055 §C rule 2)', () => {
89
91
  it('aiProviders.maxInlineMediaBytes is a non-negative integer when advertised', async () => {
90
92
  const res = await driver.get('/.well-known/openwop');
91
- if (res.status !== 200) return;
93
+ if (res.status !== 200) return softSkip('blocked', 'precondition not met — `res.status !== 200` returned early (seam, prior step, or fixture unavailable)');
92
94
  const cap = capabilityFamily((res.json as DiscoveryDoc), 'aiProviders')?.maxInlineMediaBytes;
93
- if (cap === undefined) return; // optional — soft-skip when absent
95
+ if (cap === undefined) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === undefined` returned early (optional — soft-skip when absent)'); // optional — soft-skip when absent
94
96
  expect(
95
97
  Number.isInteger(cap) && (cap as number) >= 0,
96
- driver.describe('capabilities.md §aiProviders.maxInlineMediaBytes', 'cap MUST be a non-negative integer'),
98
+ req('openwop.it.media-url-inline-cap.aiproviders-maxinlinemediabytes-is-a-non-negative-integer-when-advertised', 'capabilities.md §aiProviders.maxInlineMediaBytes', 'cap MUST be a non-negative integer'),
97
99
  ).toBe(true);
98
100
  });
99
101
 
@@ -106,24 +108,24 @@ describe.skipIf(HTTP_SKIP)('media-url-inline-cap: advertisement shape (RFC 0055
106
108
 
107
109
  it('a stored media asset is served by a tenant-scoped URL, not inlined', async () => {
108
110
  const stored = await driver.post('/v1/host/sample/media/put', { contentBase64: PNG_1x1, contentType: 'image/png' });
109
- if (stored.status === 404) return; // store seam disabled — soft-skip
110
- expect(stored.status, 'media store MUST return 201').toBe(201);
111
+ if (stored.status === 404) return softSkip('blocked', 'precondition not met — `stored.status === 404` returned early (store seam disabled — soft-skip) (seam, prior step, or fixture unavailable)'); // store seam disabled — soft-skip
112
+ expect(stored.status, req('openwop.it.media-url-inline-cap.a-stored-media-asset-is-served-by-a-tenant-scoped-url-not-inlined', 'ai-envelope.md §"Media reference payloads"', 'media store MUST return 201')).toBe(201);
111
113
  const body = stored.json as { url?: string; bytes?: number };
112
114
  expect(
113
115
  typeof body.url === 'string' && /\/v1\/host\/sample\/assets\//.test(body.url!),
114
- driver.describe('ai-envelope.md §"Media reference payloads"', 'asset MUST be served by a URL reference, not inlined'),
116
+ req('openwop.it.media-url-inline-cap.a-stored-media-asset-is-served-by-a-tenant-scoped-url-not-inlined', 'ai-envelope.md §"Media reference payloads"', 'asset MUST be served by a URL reference, not inlined'),
115
117
  ).toBe(true);
116
118
  const served = await driver.get(body.url!);
117
- expect(served.status, 'the asset URL MUST resolve').toBe(200);
119
+ expect(served.status, req('openwop.it.media-url-inline-cap.a-stored-media-asset-is-served-by-a-tenant-scoped-url-not-inlined', 'ai-envelope.md §"Media reference payloads"', 'the asset URL MUST resolve')).toBe(200);
118
120
  });
119
121
 
120
122
  it('an unminted/guessed asset token does not resolve (media-asset-url-tenant-scoped)', async () => {
121
123
  // Probe whether the serve route exists at all; soft-skip if not.
122
124
  const probe = await driver.get('/v1/host/sample/assets/probe-never-minted-token');
123
- if (probe.status === 404 && !process.env.OPENWOP_BASE_URL) return;
125
+ if (probe.status === 404 && !process.env.OPENWOP_BASE_URL) return softSkip('blocked', 'precondition not met — `probe.status === 404 && !process.env.OPENWOP_BASE_URL` returned early (seam, prior step, or fixture unavailable)');
124
126
  expect(
125
127
  probe.status,
126
- driver.describe('SECURITY/invariants.yaml#media-asset-url-tenant-scoped', 'a token not held by the caller (unguessable 256-bit) MUST NOT resolve'),
128
+ req('openwop.it.media-url-inline-cap.an-unminted-guessed-asset-token-does-not-resolve-media-asset-url-tenant-scoped', 'SECURITY/invariants.yaml#media-asset-url-tenant-scoped', 'a token not held by the caller (unguessable 256-bit) MUST NOT resolve'),
127
129
  ).toBe(404);
128
130
  });
129
131
 
@@ -135,14 +137,14 @@ describe.skipIf(HTTP_SKIP)('media-url-inline-cap: advertisement shape (RFC 0055
135
137
  // — and on the reference host, which exports debug bundles but has no node
136
138
  // that emits a media.* envelope into a run (so no media payload appears).
137
139
  const disc = await driver.get('/.well-known/openwop');
138
- if (disc.status !== 200) return;
140
+ if (disc.status !== 200) return softSkip('blocked', 'precondition not met — `disc.status !== 200` returned early (seam, prior step, or fixture unavailable)');
139
141
  const caps = discoveryFamilies(disc.json) as { aiProviders?: { maxInlineMediaBytes?: unknown }; debugBundle?: { supported?: unknown } };
140
142
  if (caps.aiProviders?.maxInlineMediaBytes === undefined || caps.debugBundle?.supported !== true) {
141
- return; // host doesn't serve media + export debug bundles — contract not exercisable
143
+ return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `caps.aiProviders?.maxInlineMediaBytes === undefined || caps.debugBundle?.supported !== true` returned early (host doesn\'t serve media + export debug bundles — …'); // host doesn't serve media + export debug bundles — contract not exercisable
142
144
  }
143
145
  // Find a recent run and inspect its debug bundle for any media.* event.
144
146
  const runs = await driver.get('/v1/runs?limit=20');
145
- if (runs.status !== 200) return;
147
+ if (runs.status !== 200) return softSkip('blocked', 'precondition not met — `runs.status !== 200` returned early (seam, prior step, or fixture unavailable)');
146
148
  const runIds = ((runs.json as { runs?: { runId?: string }[] }).runs ?? [])
147
149
  .map((r) => r.runId)
148
150
  .filter((id): id is string => typeof id === 'string');
@@ -155,9 +157,9 @@ describe.skipIf(HTTP_SKIP)('media-url-inline-cap: advertisement shape (RFC 0055
155
157
  // The §C rule-3 contract: served by URL, not inlined binary.
156
158
  expect(
157
159
  typeof ev.payload?.url === 'string' && ev.payload?.base64 === undefined,
158
- driver.describe('ai-envelope.md §"Media reference payloads"', 'a media.* payload in a debug bundle MUST be a URL reference, never inlined binary'),
160
+ req('openwop.it.media-url-inline-cap.a-media-payload-in-a-run-debug-bundle-is-referenced-by-url-not-inlined-rfc-0055', 'ai-envelope.md §"Media reference payloads"', 'a media.* payload in a debug bundle MUST be a URL reference, never inlined binary'),
159
161
  ).toBe(true);
160
- return; // asserted one — contract proven
162
+ return softSkip('blocked', 'precondition not met — `typeof ev.type === \'string\' && ev.type.startsWith(\'media.\')` returned early (asserted one — contract proven) (seam, prior step, or fixture unavailable)'); // asserted one — contract proven
161
163
  }
162
164
  }
163
165
  }
@@ -10,9 +10,9 @@
10
10
 
11
11
  import { describe, it, expect } from 'vitest';
12
12
  import { softSkip } from '../lib/soft-skip.js';
13
- import { driver } from '../lib/driver.js';
14
13
  import { pollUntilTerminal } from '../lib/polling.js';
15
14
  import { readMemoryAttributionCap, emitsWriteEvents, seedRun, memoryWrittenEvents } from '../lib/memoryAttribution.js';
15
+ import { req } from '../lib/requirement-ids.js';
16
16
 
17
17
  describe('memory-attribution-emits-on-write (RFC 0057 §A/§B)', () => {
18
18
  it('an advertised host emits memory.written carrying a stable memoryId', async () => {
@@ -23,7 +23,7 @@ describe('memory-attribution-emits-on-write (RFC 0057 §A/§B)', () => {
23
23
  try {
24
24
  await pollUntilTerminal(runId, { timeoutMs: 10_000 });
25
25
  } catch {
26
- return;
26
+ return softSkip('blocked', 'precondition not met — an earlier step threw (seam, prior step, or fixture unavailable)');
27
27
  }
28
28
  const events = await memoryWrittenEvents(runId);
29
29
  if (events.length === 0) return softSkip('blocked', 'run wrote no memory — soft-skip (events.length === 0)');
@@ -31,7 +31,7 @@ describe('memory-attribution-emits-on-write (RFC 0057 §A/§B)', () => {
31
31
  const memoryId = (e.payload as { memoryId?: unknown } | undefined)?.memoryId;
32
32
  expect(
33
33
  typeof memoryId === 'string' && memoryId.length > 0,
34
- driver.describe('RFC 0057 §B', 'memory.written.memoryId MUST be a stable, non-empty identifier'),
34
+ req('openwop.it.memory-attribution-emits-on-write.an-advertised-host-emits-memory-written-carrying-a-stable-memoryid', 'RFC 0057 §B', 'memory.written.memoryId MUST be a stable, non-empty identifier'),
35
35
  ).toBe(true);
36
36
  }
37
37
  });
@@ -44,12 +44,12 @@ describe('memory-attribution-emits-on-write (RFC 0057 §A/§B)', () => {
44
44
  try {
45
45
  await pollUntilTerminal(runId, { timeoutMs: 10_000 });
46
46
  } catch {
47
- return;
47
+ return softSkip('blocked', 'precondition not met — an earlier step threw (seam, prior step, or fixture unavailable)');
48
48
  }
49
49
  const events = await memoryWrittenEvents(runId);
50
50
  expect(
51
51
  events.length,
52
- driver.describe('RFC 0057 §A', 'a host not advertising memory.attribution MUST NOT emit memory.written'),
52
+ req('openwop.it.memory-attribution-emits-on-write.a-host-without-the-capability-emits-no-memory-written', 'RFC 0057 §A', 'a host not advertising memory.attribution MUST NOT emit memory.written'),
53
53
  ).toBe(0);
54
54
  });
55
55
  });
@@ -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 { pollUntilTerminal } from '../lib/polling.js';
18
17
  import { readMemoryAttributionCap, emitsWriteEvents, seedRun, memoryWrittenEvents } from '../lib/memoryAttribution.js';
18
+ import { req } from '../lib/requirement-ids.js';
19
19
 
20
20
  describe('memory-attribution-no-content (RFC 0057 §C)', () => {
21
21
  it('memory.written payloads carry no entry content', async () => {
@@ -26,7 +26,7 @@ describe('memory-attribution-no-content (RFC 0057 §C)', () => {
26
26
  try {
27
27
  await pollUntilTerminal(runId, { timeoutMs: 10_000 });
28
28
  } catch {
29
- return;
29
+ return softSkip('blocked', 'precondition not met — an earlier step threw (seam, prior step, or fixture unavailable)');
30
30
  }
31
31
  const events = await memoryWrittenEvents(runId);
32
32
  if (events.length === 0) return softSkip('blocked', 'run wrote no memory — soft-skip (events.length === 0)');
@@ -34,12 +34,12 @@ describe('memory-attribution-no-content (RFC 0057 §C)', () => {
34
34
  const payload = e.payload ?? {};
35
35
  expect(
36
36
  'content' in payload,
37
- driver.describe('RFC 0057 §C', 'memory.written MUST NOT carry the entry content field'),
37
+ req('openwop.it.memory-attribution-no-content.memory-written-payloads-carry-no-entry-content', 'RFC 0057 §C', 'memory.written MUST NOT carry the entry content field'),
38
38
  ).toBe(false);
39
39
  expect(
40
40
  typeof (payload as { memoryRef?: unknown }).memoryRef === 'string' &&
41
41
  typeof (payload as { memoryId?: unknown }).memoryId === 'string',
42
- driver.describe('RFC 0057 §B', 'memory.written MUST carry memoryRef + memoryId identifiers'),
42
+ req('openwop.it.memory-attribution-no-content.memory-written-payloads-carry-no-entry-content', 'RFC 0057 §B', 'memory.written MUST carry memoryRef + memoryId identifiers'),
43
43
  ).toBe(true);
44
44
  }
45
45
  });
@@ -41,6 +41,7 @@ import { softSkip } from '../lib/soft-skip.js';
41
41
  import { driver } from '../lib/driver.js';
42
42
  import { pollUntilTerminal } from '../lib/polling.js';
43
43
  import { readMemoryAttributionCap, emitsWriteEvents, seedRun, memoryWrittenEvents } from '../lib/memoryAttribution.js';
44
+ import { req } from '../lib/requirement-ids.js';
44
45
 
45
46
  function memoryIdOf(payload: Record<string, unknown> | undefined): string | null {
46
47
  const id = (payload ?? {})['memoryId'];
@@ -56,7 +57,7 @@ describe('memory-attribution-replay-stable (RFC 0057 §D)', () => {
56
57
  try {
57
58
  await pollUntilTerminal(runId, { timeoutMs: 10_000 });
58
59
  } catch {
59
- return;
60
+ return softSkip('blocked', 'precondition not met — an earlier step threw (seam, prior step, or fixture unavailable)');
60
61
  }
61
62
  const original = await memoryWrittenEvents(runId);
62
63
  if (original.length === 0) return softSkip('blocked', 'run wrote no memory — nothing to test');
@@ -83,7 +84,7 @@ describe('memory-attribution-replay-stable (RFC 0057 §D)', () => {
83
84
  const missing = [...recordedIds].filter((id) => !replayedIds.has(id));
84
85
  expect(
85
86
  missing,
86
- driver.describe(
87
+ req('openwop.it.memory-attribution-replay-stable.a-replay-mode-fork-introduces-no-memory-written-with-a-new-memoryid',
87
88
  'replay.md §"Determinism guarantees" caveat 5',
88
89
  'recorded-fact events are fixed history: a replay MUST re-emit the source run\'s ' +
89
90
  '`memory.written` events from the log. A replay whose log is SHORT of the source\'s is not ' +
@@ -97,7 +98,7 @@ describe('memory-attribution-replay-stable (RFC 0057 §D)', () => {
97
98
  const id = memoryIdOf(e.payload);
98
99
  expect(
99
100
  id !== null && recordedIds.has(id),
100
- driver.describe('RFC 0057 §D', 'a replay MUST NOT regenerate memoryId — every replayed memory.written reuses a recorded id'),
101
+ req('openwop.it.memory-attribution-replay-stable.a-replay-mode-fork-introduces-no-memory-written-with-a-new-memoryid', 'RFC 0057 §D', 'a replay MUST NOT regenerate memoryId — every replayed memory.written reuses a recorded id'),
101
102
  ).toBe(true);
102
103
  }
103
104
  });
@@ -10,16 +10,17 @@
10
10
  */
11
11
 
12
12
  import { describe, it, expect } from 'vitest';
13
- import { driver } from '../lib/driver.js';
14
13
  import { readMemoryAttributionCap } from '../lib/memoryAttribution.js';
14
+ import { req } from '../lib/requirement-ids.js';
15
+ import { softSkip } from '../lib/soft-skip.js';
15
16
 
16
17
  describe('memory-attribution-shape: advertisement (RFC 0057 §A)', () => {
17
18
  it('capabilities.memory.attribution is absent or a well-formed object', async () => {
18
19
  const cap = await readMemoryAttributionCap();
19
- if (cap === null) return; // not advertised — valid
20
+ if (cap === null) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `cap === null` returned early (not advertised — valid)'); // not advertised — valid
20
21
  expect(
21
22
  cap.supported,
22
- driver.describe('capabilities.schema.json §memory.attribution', 'memory.attribution.supported MUST be the literal true when the block is present'),
23
+ req('openwop.it.memory-attribution-shape.capabilities-memory-attribution-is-absent-or-a-well-formed-object', 'capabilities.schema.json §memory.attribution', 'memory.attribution.supported MUST be the literal true when the block is present'),
23
24
  ).toBe(true);
24
25
  if (cap.emitsWriteEvents !== undefined) {
25
26
  expect(typeof cap.emitsWriteEvents).toBe('boolean');
@@ -14,9 +14,9 @@
14
14
 
15
15
  import { describe, it, expect } from 'vitest';
16
16
  import { softSkip } from '../lib/soft-skip.js';
17
- import { driver } from '../lib/driver.js';
18
17
  import { pollUntilTerminal } from '../lib/polling.js';
19
18
  import { readMemoryAttributionCap, emitsWriteEvents, seedRun, memoryWrittenEvents } from '../lib/memoryAttribution.js';
19
+ import { req } from '../lib/requirement-ids.js';
20
20
 
21
21
  describe('memory-attribution-tenant-scoped (RFC 0057 §C)', () => {
22
22
  it("a run's memory.written events appear only on that run's stream", async () => {
@@ -27,7 +27,7 @@ describe('memory-attribution-tenant-scoped (RFC 0057 §C)', () => {
27
27
  try {
28
28
  await pollUntilTerminal(runId, { timeoutMs: 10_000 });
29
29
  } catch {
30
- return;
30
+ return softSkip('blocked', 'precondition not met — an earlier step threw (seam, prior step, or fixture unavailable)');
31
31
  }
32
32
  const events = await memoryWrittenEvents(runId);
33
33
  if (events.length === 0) return softSkip('blocked', 'precondition not met — `events.length === 0` returned early (seam, prior step, or fixture unavailable)');
@@ -37,7 +37,7 @@ describe('memory-attribution-tenant-scoped (RFC 0057 §C)', () => {
37
37
  if (typeof e.runId === 'string') {
38
38
  expect(
39
39
  e.runId,
40
- driver.describe('RFC 0057 §C', "a memory.written event MUST belong to its own run's stream (CTI-1)"),
40
+ req('openwop.it.memory-attribution-tenant-scoped.a-run-s-memory-written-events-appear-only-on-that-run-s-stream', 'RFC 0057 §C', "a memory.written event MUST belong to its own run's stream (CTI-1)"),
41
41
  ).toBe(runId);
42
42
  }
43
43
  }
@@ -36,8 +36,7 @@ import Ajv2020 from 'ajv/dist/2020.js';
36
36
  import addFormats from 'ajv-formats';
37
37
  import { SCHEMAS_DIR } from '../lib/paths.js';
38
38
  import { deriveProfiles } from '../lib/profiles.js';
39
-
40
- const why = (specRef: string, requirement: string): string => `${specRef} — ${requirement}`;
39
+ import { req } from '../lib/requirement-ids.js';
41
40
 
42
41
  function loadSchema(name: string): Record<string, unknown> {
43
42
  return JSON.parse(readFileSync(join(SCHEMAS_DIR, name), 'utf8')) as Record<string, unknown>;
@@ -63,7 +62,7 @@ describe('memory-capability-model-shape: reconciled dimensions (RFC 0080 §A, se
63
62
  for (const dim of ['writable', 'search', 'retention']) {
64
63
  expect(
65
64
  memory?.properties?.[dim],
66
- why('agent-memory.md §"Memory capability model"', `capabilities.memory.${dim} MUST be declared (RFC 0080 §A)`),
65
+ req('openwop.it.memory-capability-model-shape.capabilities-memory-declares-the-additive-writable-search-retention-dimensions', 'agent-memory.md §"Memory capability model"', `capabilities.memory.${dim} MUST be declared (RFC 0080 §A)`),
67
66
  ).toBeDefined();
68
67
  }
69
68
  });
@@ -72,7 +71,7 @@ describe('memory-capability-model-shape: reconciled dimensions (RFC 0080 §A, se
72
71
  for (const dim of ['supported', 'compaction', 'distillation', 'attribution']) {
73
72
  expect(
74
73
  memory?.properties?.[dim],
75
- why('COMPATIBILITY.md §2.1', `capabilities.memory.${dim} MUST remain (RFC 0080 is additive)`),
74
+ req('openwop.it.memory-capability-model-shape.the-pre-existing-memory-fields-are-untouched-additive-no-relocation', 'COMPATIBILITY.md §2.1', `capabilities.memory.${dim} MUST remain (RFC 0080 is additive)`),
76
75
  ).toBeDefined();
77
76
  }
78
77
  });
@@ -89,22 +88,22 @@ describe('memory-capability-model-shape: reconciled dimensions (RFC 0080 §A, se
89
88
 
90
89
  expect(
91
90
  validate({ memory: { supported: true, writable: false, search: { supported: true, modes: ['semantic', 'filter'] }, retention: { ttl: true, forget: true } } }),
92
- why('capabilities.md §memory', 'a full reconciled-memory advertisement MUST validate'),
91
+ req('openwop.it.memory-capability-model-shape.memory-search-memory-retention-validate-conforming-instances-and-reject-malforme', 'capabilities.md §memory', 'a full reconciled-memory advertisement MUST validate'),
93
92
  ).toBe(true);
94
93
 
95
94
  expect(
96
95
  validate({ memory: { retention: { ttl: 'yes' } } }),
97
- why('RFC 0080 §A', 'retention.ttl MUST be boolean'),
96
+ req('openwop.it.memory-capability-model-shape.memory-search-memory-retention-validate-conforming-instances-and-reject-malforme', 'RFC 0080 §A', 'retention.ttl MUST be boolean'),
98
97
  ).toBe(false);
99
98
 
100
99
  expect(
101
100
  validate({ memory: { search: { supported: true, modes: ['fuzzy'] } } }),
102
- why('RFC 0080 §A', 'search.modes MUST be the closed enum [semantic, filter]'),
101
+ req('openwop.it.memory-capability-model-shape.memory-search-memory-retention-validate-conforming-instances-and-reject-malforme', 'RFC 0080 §A', 'search.modes MUST be the closed enum [semantic, filter]'),
103
102
  ).toBe(false);
104
103
 
105
104
  expect(
106
105
  validate({ memory: { search: { supported: true, unknownField: 1 } } }),
107
- why('RFC 0080 §A', 'memory.search MUST be additionalProperties:false'),
106
+ req('openwop.it.memory-capability-model-shape.memory-search-memory-retention-validate-conforming-instances-and-reject-malforme', 'RFC 0080 §A', 'memory.search MUST be additionalProperties:false'),
108
107
  ).toBe(false);
109
108
  });
110
109
  });
@@ -117,11 +116,11 @@ describe('memory-capability-model-shape: degraded projection (RFC 0080 §C, serv
117
116
  .AgentInventoryEntry).properties;
118
117
  expect(
119
118
  entry?.memoryDegraded,
120
- why('agent-memory.md §C-1', 'memoryDegraded MUST be declared on the inventory entry'),
119
+ req('openwop.it.memory-capability-model-shape.agent-inventory-response-declares-memorydegraded-degradedmemorydimensions', 'agent-memory.md §C-1', 'memoryDegraded MUST be declared on the inventory entry'),
121
120
  ).toBeDefined();
122
121
  expect(
123
122
  entry?.degradedMemoryDimensions,
124
- why('agent-memory.md §C-1', 'degradedMemoryDimensions MUST be declared on the inventory entry'),
123
+ req('openwop.it.memory-capability-model-shape.agent-inventory-response-declares-memorydegraded-degradedmemorydimensions', 'agent-memory.md §C-1', 'degradedMemoryDimensions MUST be declared on the inventory entry'),
125
124
  ).toBeDefined();
126
125
  });
127
126
 
@@ -131,7 +130,7 @@ describe('memory-capability-model-shape: degraded projection (RFC 0080 §C, serv
131
130
  const enumVals = entry?.degradedMemoryDimensions?.items?.enum ?? [];
132
131
  expect(
133
132
  [...enumVals].sort(),
134
- why('agent-memory.md §A', 'the degraded-dimension enum MUST be the eight reconciled dimensions'),
133
+ req('openwop.it.memory-capability-model-shape.degradedmemorydimensions-enumerates-exactly-the-eight-a-dimension-names', 'agent-memory.md §A', 'the degraded-dimension enum MUST be the eight reconciled dimensions'),
135
134
  ).toEqual([...DIMENSIONS].sort());
136
135
  });
137
136
 
@@ -144,11 +143,11 @@ describe('memory-capability-model-shape: degraded projection (RFC 0080 §C, serv
144
143
  };
145
144
  expect(
146
145
  validate({ total: 1, agents: [{ ...base, memoryDegraded: true, degradedMemoryDimensions: ['write', 'long-term-durability'] }] }),
147
- why('agent-memory.md §C-1', 'a degraded inventory entry MUST validate'),
146
+ req('openwop.it.memory-capability-model-shape.the-inventory-schema-round-trips-a-degraded-entry-and-rejects-an-out-of-enum-dim', 'agent-memory.md §C-1', 'a degraded inventory entry MUST validate'),
148
147
  ).toBe(true);
149
148
  expect(
150
149
  validate({ total: 1, agents: [{ ...base, memoryDegraded: true, degradedMemoryDimensions: ['telepathy'] }] }),
151
- why('agent-memory.md §C-1', 'an out-of-enum degraded dimension MUST be rejected'),
150
+ req('openwop.it.memory-capability-model-shape.the-inventory-schema-round-trips-a-degraded-entry-and-rejects-an-out-of-enum-dim', 'agent-memory.md §C-1', 'an out-of-enum degraded dimension MUST be rejected'),
152
151
  ).toBe(false);
153
152
  });
154
153
  });
@@ -165,7 +164,7 @@ describe('memory-capability-model-shape: openwop-memory derivation (RFC 0080 §D
165
164
  } as Record<string, unknown>;
166
165
  expect(
167
166
  deriveProfiles(c).includes('openwop-memory'),
168
- why('profiles.md §openwop-memory', 'a read/write + long-term host MUST derive openwop-memory'),
167
+ req('openwop.it.memory-capability-model-shape.deriveprofiles-surfaces-openwop-memory-for-a-read-write-long-term-host', 'profiles.md §openwop-memory', 'a read/write + long-term host MUST derive openwop-memory'),
169
168
  ).toBe(true);
170
169
  });
171
170
 
@@ -180,7 +179,7 @@ describe('memory-capability-model-shape: openwop-memory derivation (RFC 0080 §D
180
179
  } as Record<string, unknown>;
181
180
  expect(
182
181
  deriveProfiles(c).includes('openwop-memory'),
183
- why('profiles.md §openwop-memory', 'a read-only host MUST NOT derive openwop-memory'),
182
+ req('openwop.it.memory-capability-model-shape.deriveprofiles-withholds-openwop-memory-from-a-read-only-writable-false-host', 'profiles.md §openwop-memory', 'a read-only host MUST NOT derive openwop-memory'),
184
183
  ).toBe(false);
185
184
  });
186
185
  });
@@ -28,6 +28,7 @@ import { describe, it, expect } from 'vitest';
28
28
  import { softSkip } from '../lib/soft-skip.js';
29
29
  import { driver } from '../lib/driver.js';
30
30
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
31
+ import { req } from '../lib/requirement-ids.js';
31
32
 
32
33
  const MEMORY_REF = 'mem_tenant:default_agent:conformance-rfc0012-event_longTerm';
33
34
 
@@ -79,26 +80,26 @@ describe('memory-compaction-event-emitted: canonical memory.compacted payload sh
79
80
  payload?: Record<string, unknown>;
80
81
  };
81
82
 
82
- expect(event.type, driver.describe(
83
+ expect(event.type, req('openwop.it.memory-compaction-event-emitted.compaction-run-returns-a-canonical-memorycompacted-payload',
83
84
  'observability.md §"Canonical run lifecycle event names"',
84
85
  'event MUST be type=memory.compacted',
85
86
  )).toBe('memory.compacted');
86
87
 
87
88
  const payload = event.payload ?? {};
88
89
 
89
- expect(typeof payload.memoryRef, driver.describe(
90
+ expect(typeof payload.memoryRef, req('openwop.it.memory-compaction-event-emitted.compaction-run-returns-a-canonical-memorycompacted-payload',
90
91
  'RFC 0012 §B / run-event-payloads.schema.json §memoryCompacted',
91
92
  'memoryRef MUST be a non-empty string',
92
93
  )).toBe('string');
93
94
  expect((payload.memoryRef as string).length).toBeGreaterThan(0);
94
95
 
95
- expect(typeof payload.outputId, driver.describe(
96
+ expect(typeof payload.outputId, req('openwop.it.memory-compaction-event-emitted.compaction-run-returns-a-canonical-memorycompacted-payload',
96
97
  'RFC 0012 §B',
97
98
  'outputId MUST be a string identifying the distilled entry',
98
99
  )).toBe('string');
99
100
  expect((payload.outputId as string).length).toBeGreaterThan(0);
100
101
 
101
- expect(Number.isInteger(payload.sourceCount), driver.describe(
102
+ expect(Number.isInteger(payload.sourceCount), req('openwop.it.memory-compaction-event-emitted.compaction-run-returns-a-canonical-memorycompacted-payload',
102
103
  'RFC 0012 §B',
103
104
  'sourceCount MUST be an integer',
104
105
  )).toBe(true);
@@ -106,7 +107,7 @@ describe('memory-compaction-event-emitted: canonical memory.compacted payload sh
106
107
 
107
108
  expect(['host-managed', 'client-requested', 'both']).toContain(payload.trigger);
108
109
 
109
- expect(Number.isInteger(payload.byteSize), driver.describe(
110
+ expect(Number.isInteger(payload.byteSize), req('openwop.it.memory-compaction-event-emitted.compaction-run-returns-a-canonical-memorycompacted-payload',
110
111
  'RFC 0012 §B',
111
112
  'byteSize MUST be an integer',
112
113
  )).toBe(true);
@@ -115,7 +116,7 @@ describe('memory-compaction-event-emitted: canonical memory.compacted payload sh
115
116
  if (payload.sourceIds !== undefined) {
116
117
  expect(Array.isArray(payload.sourceIds)).toBe(true);
117
118
  for (const id of payload.sourceIds as unknown[]) {
118
- expect(typeof id, 'sourceIds entries MUST be strings').toBe('string');
119
+ expect(typeof id, req('openwop.it.memory-compaction-event-emitted.compaction-run-returns-a-canonical-memorycompacted-payload', 'RFC 0012 §B', 'sourceIds entries MUST be strings')).toBe('string');
119
120
  expect((id as string).length).toBeGreaterThan(0);
120
121
  }
121
122
  }
@@ -22,6 +22,7 @@ import { describe, it, expect } from 'vitest';
22
22
  import { softSkip } from '../lib/soft-skip.js';
23
23
  import { driver } from '../lib/driver.js';
24
24
  import { capabilityFamily } from '../lib/discovery-capabilities.js';
25
+ import { req } from '../lib/requirement-ids.js';
25
26
 
26
27
  const MEMORY_REF = 'mem_tenant:default_agent:conformance-rfc0012-tag_longTerm';
27
28
  const COMPACTED_FROM_RE = /^compacted-from:[^\s:][^\s]*$/;
@@ -91,7 +92,7 @@ describe('memory-compaction-provenance-tag: compacted-from:<id> tag follows §C
91
92
  console.warn('[rfc0012-tag] host does not expose memory:list at /v1/memory/{ref}; skipping tag inspection (canonical provenance signal remains the memory.compacted event itself)');
92
93
  return softSkip('blocked', '[rfc0012-tag] host does not expose memory:list at /v1/memory/{ref}; skipping tag inspection (canonical provenance signal remains the memory.compacted event itself)');
93
94
  }
94
- expect(listRes.status, 'memory:list MUST return 200 when reachable').toBe(200);
95
+ expect(listRes.status, req('openwop.it.memory-compaction-provenance-tag.compacted-entry-carries-a-well-formed-compacted-from-tag-or-omits-it-cleanly-no', 'RFC 0012 §C', 'memory:list MUST return 200 when reachable')).toBe(200);
95
96
 
96
97
  const body = (listRes.json as MemoryListResponse) ?? {};
97
98
  const entries = body.entries ?? [];
@@ -110,7 +111,7 @@ describe('memory-compaction-provenance-tag: compacted-from:<id> tag follows §C
110
111
  console.warn('[rfc0012-tag] output entry has no compacted-from:<id> tag — RFC 0012 §C is SHOULD, not MUST; pass with warning');
111
112
  return softSkip('inapplicable', '[rfc0012-tag] output entry has no compacted-from:<id> tag — RFC 0012 §C is SHOULD, not MUST; pass with warning');
112
113
  }
113
- expect(provenance, driver.describe(
114
+ expect(provenance, req('openwop.it.memory-compaction-provenance-tag.compacted-entry-carries-a-well-formed-compacted-from-tag-or-omits-it-cleanly-no',
114
115
  'RFC 0012 §C',
115
116
  'compacted-from tag MUST match `compacted-from:<id>` shape (non-empty id, no whitespace) when present',
116
117
  )).toMatch(COMPACTED_FROM_RE);