@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.
- package/README.md +11 -2
- package/dist/cli.js +54 -1
- package/dist/lib/paths.js +25 -3
- package/dist/lib/requirement-ids.js +34 -4
- package/dist/lib/scenario-disposition.js +1 -0
- package/dist/lib/spec-coherence.js +13 -32
- package/dist/spec-artifacts.lock.json +5 -0
- package/package.json +11 -33
- package/requirements.json +20303 -11809
- package/scenario-majors.json +1343 -0
- package/schemas/CORPUS-STAMP.json +138 -6
- package/src/cli.ts +47 -1
- package/src/global-setup.ts +3 -2
- package/src/lib/corpus-stamp.ts +29 -1
- package/src/lib/paths.ts +25 -3
- package/src/lib/requirement-ids.ts +33 -4
- package/src/lib/scenario-disposition.ts +1 -0
- package/src/lib/spec-coherence.ts +15 -32
- package/src/scenarios/a2a-1-0-agent-card.test.ts +17 -16
- package/src/scenarios/a2a-1-0-task-roundtrip.test.ts +11 -10
- package/src/scenarios/a2a-card-runtime-consistency.test.ts +18 -17
- package/src/scenarios/a2a-peer-authority.test.ts +7 -6
- package/src/scenarios/a2a-task-roundtrip.test.ts +30 -29
- package/src/scenarios/a2a-version-negotiation.test.ts +16 -14
- package/src/scenarios/a2ui-surface-degrades.test.ts +5 -3
- package/src/scenarios/a2ui-surface-delta-transport.test.ts +35 -33
- package/src/scenarios/a2ui-surface-replay.test.ts +6 -4
- package/src/scenarios/a2ui-surface-shape.test.ts +11 -10
- package/src/scenarios/a2ui-surface-version-refusal.test.ts +6 -4
- package/src/scenarios/a2ui-untrusted-blocks-approval.test.ts +5 -3
- package/src/scenarios/agent-capability-degraded-projection.test.ts +12 -11
- package/src/scenarios/agent-channel-dispatch.test.ts +18 -16
- package/src/scenarios/agent-deployment-lifecycle.test.ts +20 -19
- package/src/scenarios/agent-deployment-shape.test.ts +22 -24
- package/src/scenarios/agent-eval-run.test.ts +19 -18
- package/src/scenarios/agent-eval-suite-shape.test.ts +20 -22
- package/src/scenarios/agent-live-allowlist-enforced.test.ts +6 -5
- package/src/scenarios/agent-live-invocation-bracket.test.ts +13 -12
- package/src/scenarios/agent-live-runtime-shape.test.ts +10 -12
- package/src/scenarios/agent-live-structured-output.test.ts +7 -6
- package/src/scenarios/agent-loop-iteration-monotonic.test.ts +3 -3
- package/src/scenarios/agent-loop-stateful-resume.test.ts +2 -2
- package/src/scenarios/agent-loop-version5-shape.test.ts +4 -4
- package/src/scenarios/agent-loop-workspace-snapshot.test.ts +3 -3
- package/src/scenarios/agent-manifest-role-profile.test.ts +9 -9
- package/src/scenarios/agent-manifest-runtime.test.ts +13 -12
- package/src/scenarios/agent-org-chart-scoping.test.ts +14 -13
- package/src/scenarios/agent-org-chart-shape.test.ts +11 -13
- package/src/scenarios/agent-platform-aggregate-evidence.test.ts +5 -4
- package/src/scenarios/agent-platform-profile.test.ts +18 -19
- package/src/scenarios/agent-requires-capabilities-shape.test.ts +4 -4
- package/src/scenarios/agent-roster-attribution.test.ts +18 -17
- package/src/scenarios/agent-roster-shape.test.ts +17 -19
- package/src/scenarios/agent-verifier-shape.test.ts +11 -11
- package/src/scenarios/agentConfidenceEscalation.test.ts +2 -1
- package/src/scenarios/agentMemoryCrossTenantIsolation.test.ts +6 -5
- package/src/scenarios/agentMemoryRedactionContract.test.ts +2 -1
- package/src/scenarios/agentMemoryRoundTrip.test.ts +2 -1
- package/src/scenarios/agentMemoryTtlExpiry.test.ts +4 -3
- package/src/scenarios/agentMessageReducer.test.ts +2 -1
- package/src/scenarios/agentMetadata.test.ts +2 -1
- package/src/scenarios/agentPackCatalog.test.ts +23 -21
- package/src/scenarios/agentPackExport.test.ts +4 -2
- package/src/scenarios/agentPackHandoffSchemaValidation.test.ts +5 -4
- package/src/scenarios/agentPackInstall.test.ts +4 -2
- package/src/scenarios/agentPackProvenance.test.ts +2 -1
- package/src/scenarios/agentReasoningEvents.test.ts +3 -2
- package/src/scenarios/agentReasoningStreaming.test.ts +11 -10
- package/src/scenarios/agents-run-tool-allowlist.test.ts +14 -12
- package/src/scenarios/ai-envelope-shape.test.ts +31 -29
- package/src/scenarios/aiEnvelope.capBreached.test.ts +26 -24
- package/src/scenarios/aiEnvelope.contractRefusal.test.ts +36 -34
- package/src/scenarios/aiEnvelope.correlationReplay.test.ts +17 -15
- package/src/scenarios/aiEnvelope.redaction.test.ts +22 -20
- package/src/scenarios/aiEnvelope.schemaDrift.test.ts +18 -16
- package/src/scenarios/aiEnvelope.trustBoundaryPropagation.test.ts +38 -36
- package/src/scenarios/aiEnvelope.universalKinds.test.ts +31 -29
- package/src/scenarios/aiproviders-input-shape.test.ts +5 -5
- package/src/scenarios/aiproviders-realtimevoice-shape.test.ts +14 -16
- package/src/scenarios/aiproviders-selfhosted-honesty.test.ts +6 -4
- package/src/scenarios/aiproviders-selfhosted-shape.test.ts +15 -17
- package/src/scenarios/aiproviders-speechsynth-shape.test.ts +6 -8
- package/src/scenarios/aiproviders-subscription-scope.test.ts +7 -8
- package/src/scenarios/anonymous-actor-audit-opaque.test.ts +9 -8
- package/src/scenarios/anonymous-actor-default-deny.test.ts +10 -9
- package/src/scenarios/anonymous-actor-egress-guarded.test.ts +6 -5
- package/src/scenarios/anonymous-actor-no-secret-reach.test.ts +7 -6
- package/src/scenarios/anonymous-actor-shape.test.ts +17 -19
- package/src/scenarios/anonymous-actor-write-gated.test.ts +9 -8
- package/src/scenarios/append-ordering.test.ts +7 -5
- package/src/scenarios/approval-gate-events.test.ts +4 -3
- package/src/scenarios/approval-gate-flow.test.ts +4 -3
- package/src/scenarios/approval-payload.test.ts +5 -4
- package/src/scenarios/artifact-auth.test.ts +7 -6
- package/src/scenarios/artifact-type-pack-install.test.ts +6 -6
- package/src/scenarios/artifact-type-pack-manifest-validation.test.ts +9 -8
- package/src/scenarios/artifact-type-registration-source.test.ts +20 -20
- package/src/scenarios/artifact-type-store-emission.test.ts +15 -18
- package/src/scenarios/artifact-type-store-without-render.test.ts +4 -4
- package/src/scenarios/audit-log-integrity.test.ts +8 -6
- package/src/scenarios/auth-api-key-rotation.test.ts +11 -9
- package/src/scenarios/auth-mtls.test.ts +22 -20
- package/src/scenarios/auth-oauth2-client-credentials.test.ts +16 -14
- package/src/scenarios/auth-oidc-user-bearer.test.ts +26 -24
- package/src/scenarios/auth-saml-profile.test.ts +14 -12
- package/src/scenarios/auth-scim-profile.test.ts +3 -2
- package/src/scenarios/auth-subject-link-key-class.test.ts +8 -7
- package/src/scenarios/auth-subject-link.test.ts +11 -10
- package/src/scenarios/auth.test.ts +5 -4
- package/src/scenarios/authorization-fail-closed.test.ts +3 -2
- package/src/scenarios/authorization-roles-shape.test.ts +9 -7
- package/src/scenarios/blob-cross-tenant-isolation.test.ts +8 -6
- package/src/scenarios/blob-presign-expiry.test.ts +12 -10
- package/src/scenarios/blob-roundtrip.test.ts +0 -0
- package/src/scenarios/budget-enforcement.test.ts +15 -14
- package/src/scenarios/budget-policy-shape.test.ts +18 -19
- package/src/scenarios/bulk-cancel.test.ts +9 -8
- package/src/scenarios/byok-auth-modes.test.ts +13 -14
- package/src/scenarios/byok-roundtrip.test.ts +12 -10
- package/src/scenarios/cache-cross-tenant-isolation.test.ts +8 -6
- package/src/scenarios/cache-ttl-expiry.test.ts +7 -5
- package/src/scenarios/callai-multimodal.test.ts +5 -3
- package/src/scenarios/cancellation.test.ts +6 -5
- package/src/scenarios/cap-breach.test.ts +15 -14
- package/src/scenarios/capability-arm-witness.test.ts +5 -3
- package/src/scenarios/certification-bundle-non-vacuous.test.ts +20 -19
- package/src/scenarios/certification-bundle-redaction.test.ts +11 -10
- package/src/scenarios/certification-bundle-v2.test.ts +11 -10
- package/src/scenarios/chain-compensation-expansion.test.ts +14 -13
- package/src/scenarios/chain-produced-var-roundtrip.test.ts +13 -14
- package/src/scenarios/chain-subchain-cycle-rejected.test.ts +9 -10
- package/src/scenarios/chain-subchain-fanout.test.ts +8 -9
- package/src/scenarios/chain-subchain-sibling.test.ts +14 -16
- package/src/scenarios/channel-presence-behavioral.test.ts +9 -7
- package/src/scenarios/channel-presence-shape.test.ts +11 -12
- package/src/scenarios/channel-ttl.test.ts +6 -5
- package/src/scenarios/chat-card-pack-execution.test.ts +4 -4
- package/src/scenarios/chat-card-pack-manifest-validation.test.ts +9 -8
- package/src/scenarios/commitment-fired.test.ts +6 -5
- package/src/scenarios/compensation-behavior.test.ts +24 -23
- package/src/scenarios/compensation-recovery.test.ts +28 -27
- package/src/scenarios/configurable-schema.test.ts +8 -6
- package/src/scenarios/conformance-advertised-seam-required.test.ts +6 -5
- package/src/scenarios/conformance-execution-witness.test.ts +9 -8
- package/src/scenarios/connection-pack-apihosts.test.ts +19 -17
- package/src/scenarios/connection-pack-manifest-valid.test.ts +12 -11
- package/src/scenarios/connection-pack-no-credential-material.test.ts +8 -6
- package/src/scenarios/connection-pack-reach-exclusive.test.ts +5 -4
- package/src/scenarios/connection-pack-write-reconsent.test.ts +6 -4
- package/src/scenarios/connection-provider-resolution.test.ts +18 -16
- package/src/scenarios/connector-manifest-validity.test.ts +8 -7
- package/src/scenarios/context-budget-transcript-bound.test.ts +17 -15
- package/src/scenarios/context-summarization-replay.test.ts +14 -12
- package/src/scenarios/contract-provenance.test.ts +18 -18
- package/src/scenarios/conversation-turn-model-provenance-shape.test.ts +14 -15
- package/src/scenarios/conversationCapabilityNegotiation.test.ts +2 -1
- package/src/scenarios/conversationLifecycle.test.ts +2 -1
- package/src/scenarios/conversationReplayDeterminism.test.ts +4 -2
- package/src/scenarios/conversationVsLegacySuspend.test.ts +2 -1
- package/src/scenarios/core-standard-profile.test.ts +8 -9
- package/src/scenarios/cost-attribution.test.ts +23 -21
- package/src/scenarios/credential-payload-redaction.test.ts +4 -3
- package/src/scenarios/credentials-capability-shape.test.ts +5 -4
- package/src/scenarios/cross-engine-append-behavior.test.ts +11 -10
- package/src/scenarios/cross-engine-append-ordering.test.ts +4 -3
- package/src/scenarios/cross-host-ancestry-endpoint.test.ts +11 -10
- package/src/scenarios/cross-host-causation-shape.test.ts +7 -6
- package/src/scenarios/cross-workspace-isolation.test.ts +4 -3
- package/src/scenarios/data-residency-admission.test.ts +15 -14
- package/src/scenarios/deadletter-capability-shape.test.ts +6 -4
- package/src/scenarios/deadletter-retry-exhaustion.test.ts +4 -3
- package/src/scenarios/debug-bundle-truncation.test.ts +9 -7
- package/src/scenarios/debugBundle.test.ts +25 -23
- package/src/scenarios/discovery-families-view.test.ts +5 -4
- package/src/scenarios/discovery.test.ts +30 -29
- package/src/scenarios/dispatch-cross-worker-handoff.test.ts +10 -8
- package/src/scenarios/dispatch-fanout-parallel.test.ts +24 -22
- package/src/scenarios/dispatch-input-mapping.test.ts +12 -10
- package/src/scenarios/dispatch-output-mapping.test.ts +9 -7
- package/src/scenarios/dispatch-per-item-input.test.ts +22 -20
- package/src/scenarios/dispatchLoop.test.ts +3 -2
- package/src/scenarios/distillation-index-roundtrip.test.ts +3 -3
- package/src/scenarios/distillation-secret-carryforward.test.ts +2 -2
- package/src/scenarios/distillation-shape.test.ts +4 -4
- package/src/scenarios/distillation-stable-archive.test.ts +6 -6
- package/src/scenarios/distillation-token-budget.test.ts +5 -5
- package/src/scenarios/durability-poison-exhaustion.test.ts +7 -6
- package/src/scenarios/egress-audience-binding.test.ts +11 -10
- package/src/scenarios/egress-decision-content-free.test.ts +6 -5
- package/src/scenarios/egress-provenance-shape.test.ts +17 -18
- package/src/scenarios/envelope-completion-distinguishes-truncation.test.ts +27 -25
- package/src/scenarios/envelope-nl-to-format-engaged.test.ts +19 -17
- package/src/scenarios/envelope-reasoning-secret-redaction.test.ts +28 -26
- package/src/scenarios/envelope-reasoning-shape.test.ts +19 -17
- package/src/scenarios/envelope-recovery-applied.test.ts +24 -22
- package/src/scenarios/envelope-refusal-shape.test.ts +31 -29
- package/src/scenarios/envelope-rendering-hint.test.ts +5 -4
- package/src/scenarios/envelope-retry-attempted.test.ts +33 -31
- package/src/scenarios/envelope-retry-exhausted.test.ts +22 -20
- package/src/scenarios/envelope-tier-one-subset-static.test.ts +9 -7
- package/src/scenarios/envelope-truncated.test.ts +19 -17
- package/src/scenarios/envelope-truncation-cap-exhaustion.test.ts +19 -17
- package/src/scenarios/envelope-variant-discriminator-static.test.ts +4 -3
- package/src/scenarios/errors.test.ts +20 -19
- package/src/scenarios/eventOrdering.test.ts +16 -14
- package/src/scenarios/exec-not-protocol-tier.test.ts +5 -7
- package/src/scenarios/experimental-tier-shape.test.ts +17 -15
- package/src/scenarios/export-bundle-portability.test.ts +17 -17
- package/src/scenarios/failure-path.test.ts +7 -6
- package/src/scenarios/feedback-capability-shape.test.ts +4 -3
- package/src/scenarios/feedback-correction-redaction.test.ts +2 -1
- package/src/scenarios/feedback-cross-tenant-isolation.test.ts +2 -1
- package/src/scenarios/feedback-fork-not-copied.test.ts +3 -2
- package/src/scenarios/feedback-on-terminal-run.test.ts +3 -2
- package/src/scenarios/feedback-record-and-list.test.ts +2 -1
- package/src/scenarios/feedback-unsupported-501.test.ts +2 -1
- package/src/scenarios/fixtures-gating.test.ts +29 -28
- package/src/scenarios/fixtures-valid.test.ts +16 -15
- package/src/scenarios/form-content-instantiation.test.ts +15 -14
- package/src/scenarios/frontend-plugin-packs.test.ts +29 -27
- package/src/scenarios/fs-path-traversal.test.ts +14 -12
- package/src/scenarios/goal-standing-continuation.test.ts +21 -21
- package/src/scenarios/grpc-transport.test.ts +9 -7
- package/src/scenarios/heartbeat-capability-shape.test.ts +3 -3
- package/src/scenarios/heartbeat-fires-once-per-tick.test.ts +2 -2
- package/src/scenarios/heartbeat-idempotent-no-spam.test.ts +3 -3
- package/src/scenarios/heartbeat-runtime-bound.test.ts +2 -2
- package/src/scenarios/highConcurrency.test.ts +14 -13
- package/src/scenarios/host-callback-declaration.test.ts +8 -7
- package/src/scenarios/http-client-ssrf.test.ts +7 -5
- package/src/scenarios/i18n-negotiation.test.ts +14 -12
- package/src/scenarios/idempotency-concurrent-claim.test.ts +14 -13
- package/src/scenarios/idempotency-key-determinism.test.ts +20 -18
- package/src/scenarios/idempotency.test.ts +8 -7
- package/src/scenarios/idempotencyRetry.test.ts +13 -11
- package/src/scenarios/identity-owner-shape.test.ts +6 -5
- package/src/scenarios/identity-passthrough.test.ts +4 -3
- package/src/scenarios/interrupt-approval.test.ts +6 -5
- package/src/scenarios/interrupt-approver-routing.test.ts +15 -15
- package/src/scenarios/interrupt-auth-required-resume.test.ts +5 -3
- package/src/scenarios/interrupt-clarification.test.ts +4 -3
- package/src/scenarios/interrupt-external-event-correlation.test.ts +6 -5
- package/src/scenarios/interrupt-parent-child-cascade.test.ts +4 -3
- package/src/scenarios/interrupt-quorum-resolution.test.ts +5 -4
- package/src/scenarios/interrupt-token-matrix.test.ts +8 -6
- package/src/scenarios/interruptRace.test.ts +12 -10
- package/src/scenarios/kv-atomic-increment.test.ts +11 -9
- package/src/scenarios/kv-cas.test.ts +14 -12
- package/src/scenarios/kv-cross-tenant-isolation.test.ts +12 -10
- package/src/scenarios/kv-ttl-expiry.test.ts +7 -5
- package/src/scenarios/localized-content-delivery.test.ts +24 -26
- package/src/scenarios/maliciousManifest.test.ts +10 -8
- package/src/scenarios/mcp-2026-07-28-discover.test.ts +15 -14
- package/src/scenarios/mcp-cache-tenant-scope.test.ts +6 -5
- package/src/scenarios/mcp-current-auth-boundary.test.ts +7 -6
- package/src/scenarios/mcp-discoverability.test.ts +9 -7
- package/src/scenarios/mcp-extension-opacity.test.ts +7 -6
- package/src/scenarios/mcp-mrtr-roundtrip.test.ts +18 -17
- package/src/scenarios/mcp-server-elicitation-bridge.test.ts +13 -12
- package/src/scenarios/mcp-server-prompt-roundtrip.test.ts +11 -10
- package/src/scenarios/mcp-server-resource-roundtrip.test.ts +11 -10
- package/src/scenarios/mcp-server-sampling-bridge.test.ts +12 -11
- package/src/scenarios/mcp-server-tool-roundtrip.test.ts +14 -13
- package/src/scenarios/mcp-server-untrusted-args.test.ts +14 -13
- package/src/scenarios/mcp-stateless-request.test.ts +11 -10
- package/src/scenarios/mcp-tool-roundtrip.test.ts +4 -3
- package/src/scenarios/mcp-toolcall-redaction.test.ts +4 -3
- package/src/scenarios/mcp-version-negotiation.test.ts +15 -14
- package/src/scenarios/media-url-inline-cap.test.ts +21 -19
- package/src/scenarios/memory-attribution-emits-on-write.test.ts +5 -5
- package/src/scenarios/memory-attribution-no-content.test.ts +4 -4
- package/src/scenarios/memory-attribution-replay-stable.test.ts +4 -3
- package/src/scenarios/memory-attribution-shape.test.ts +4 -3
- package/src/scenarios/memory-attribution-tenant-scoped.test.ts +3 -3
- package/src/scenarios/memory-capability-model-shape.test.ts +14 -15
- package/src/scenarios/memory-compaction-event-emitted.test.ts +7 -6
- package/src/scenarios/memory-compaction-provenance-tag.test.ts +3 -2
- package/src/scenarios/memory-compaction-sr1-carry-forward.test.ts +7 -6
- package/src/scenarios/memory-consolidation-idempotent.test.ts +5 -4
- package/src/scenarios/memory-consolidation-shape.test.ts +9 -11
- package/src/scenarios/memory-degraded-projection.test.ts +10 -9
- package/src/scenarios/memory-injection-budget.test.ts +15 -14
- package/src/scenarios/metric-emission.test.ts +4 -3
- package/src/scenarios/model-capability-insufficient.test.ts +19 -17
- package/src/scenarios/model-capability-substituted.test.ts +20 -18
- package/src/scenarios/multi-agent-confidence-escalation.test.ts +12 -11
- package/src/scenarios/multi-agent-handoff-state-machine.test.ts +10 -9
- package/src/scenarios/multi-agent-memory-lifecycle.test.ts +11 -10
- package/src/scenarios/multi-node-ordering.test.ts +4 -3
- package/src/scenarios/multi-party-conversation-behavioral.test.ts +6 -6
- package/src/scenarios/multi-party-conversation-shape.test.ts +21 -23
- package/src/scenarios/multi-region-idempotency-behavior.test.ts +16 -15
- package/src/scenarios/multi-region-idempotency.test.ts +6 -5
- package/src/scenarios/node-failed-payload-shape.test.ts +5 -4
- package/src/scenarios/node-module-required-capabilities-shape.test.ts +10 -8
- package/src/scenarios/oauth-authorization-code-roundtrip.test.ts +5 -4
- package/src/scenarios/oauth-capability-shape.test.ts +5 -4
- package/src/scenarios/oauth-connector-redaction.test.ts +4 -3
- package/src/scenarios/openapi-resolved-paths.test.ts +6 -5
- package/src/scenarios/orchestratorConservativePath.test.ts +2 -1
- package/src/scenarios/orchestratorDispatch.test.ts +2 -1
- package/src/scenarios/orchestratorTermination.test.ts +2 -1
- package/src/scenarios/org-position-no-authority-escalation.test.ts +2 -2
- package/src/scenarios/otel-collector-canary-inspection.test.ts +8 -7
- package/src/scenarios/otel-emission-grpc.test.ts +3 -2
- package/src/scenarios/otel-emission.test.ts +6 -5
- package/src/scenarios/otel-trace-propagation-subworkflow.test.ts +7 -6
- package/src/scenarios/otel-trace-propagation.test.ts +2 -1
- package/src/scenarios/owner-subject-echo.test.ts +13 -12
- package/src/scenarios/owner-subject-shape.test.ts +11 -10
- package/src/scenarios/pack-manifest-extension-opacity.test.ts +8 -8
- package/src/scenarios/pack-registry-isolation.test.ts +4 -3
- package/src/scenarios/pack-registry-publish.test.ts +65 -63
- package/src/scenarios/pack-registry.test.ts +38 -36
- package/src/scenarios/pause-resume.test.ts +18 -16
- package/src/scenarios/policies.test.ts +20 -18
- package/src/scenarios/production-backpressure.test.ts +18 -16
- package/src/scenarios/production-retention-expiry.test.ts +8 -6
- package/src/scenarios/profile-discovery-core-alias.test.ts +13 -11
- package/src/scenarios/profileDerivation.test.ts +34 -33
- package/src/scenarios/prompt-all-four-kinds-events.test.ts +11 -9
- package/src/scenarios/prompt-composed-secret-redaction.test.ts +11 -9
- package/src/scenarios/prompt-composed-trust-marker.test.ts +10 -8
- package/src/scenarios/prompt-end-to-end-events.test.ts +17 -15
- package/src/scenarios/prompt-list-and-fetch.test.ts +16 -14
- package/src/scenarios/prompt-mutable-lifecycle.test.ts +13 -11
- package/src/scenarios/prompt-mutation-workspace-membership-enforced.test.ts +6 -4
- package/src/scenarios/prompt-pack-install.test.ts +14 -12
- package/src/scenarios/prompt-prefix-cache.test.ts +19 -17
- package/src/scenarios/prompt-read-workspace-membership-enforced.test.ts +11 -9
- package/src/scenarios/prompt-render-deterministic.test.ts +19 -17
- package/src/scenarios/prompt-resolution-chain-agent-intrinsic.test.ts +7 -5
- package/src/scenarios/prompt-resolution-chain-event.test.ts +12 -10
- package/src/scenarios/prompt-resolution-chain-fallback-cascade.test.ts +10 -8
- package/src/scenarios/prompt-resolution-chain-node-wins.test.ts +8 -6
- package/src/scenarios/prompt-template-shape.test.ts +30 -28
- package/src/scenarios/proposal-reviewable-learning.test.ts +19 -19
- package/src/scenarios/protocol-versions-array.test.ts +10 -9
- package/src/scenarios/provider-usage.test.ts +17 -15
- package/src/scenarios/providerPolicyEnforcement.test.ts +16 -14
- package/src/scenarios/purpose-propagation.test.ts +23 -21
- package/src/scenarios/queue-ack-nack-dlq.test.ts +12 -10
- package/src/scenarios/queue-cross-tenant-isolation.test.ts +8 -6
- package/src/scenarios/queue-publish-consume-roundtrip.test.ts +10 -8
- package/src/scenarios/rate-limit-envelope.test.ts +6 -5
- package/src/scenarios/redaction.test.ts +13 -11
- package/src/scenarios/redactionAdversarial.test.ts +11 -9
- package/src/scenarios/registry-public.test.ts +12 -11
- package/src/scenarios/replay-divergence-at-refusal.test.ts +16 -15
- package/src/scenarios/replay-fanout-suppression.test.ts +16 -15
- package/src/scenarios/replay-fork-arbitrary.test.ts +24 -23
- package/src/scenarios/replay-fork.test.ts +20 -19
- package/src/scenarios/replay-llm-cache-key-portable.test.ts +11 -9
- package/src/scenarios/replay-llm-cache-key.test.ts +22 -21
- package/src/scenarios/replay-observable-sequence-determinism.test.ts +4 -3
- package/src/scenarios/replay-retention-expiry.test.ts +11 -9
- package/src/scenarios/replay-side-effect-suppression.test.ts +21 -19
- package/src/scenarios/replayDeterminism.test.ts +13 -12
- package/src/scenarios/requirement-ledger.test.ts +15 -14
- package/src/scenarios/restart-during-run.test.ts +3 -2
- package/src/scenarios/route-coverage.test.ts +20 -19
- package/src/scenarios/run-diff.test.ts +22 -20
- package/src/scenarios/run-execution-bounds-shape.test.ts +14 -12
- package/src/scenarios/run-transport-economy.test.ts +13 -11
- package/src/scenarios/runner-ledger.test.ts +17 -16
- package/src/scenarios/runs-lifecycle.test.ts +7 -6
- package/src/scenarios/runtime-capabilities.test.ts +12 -10
- package/src/scenarios/runtime-requires-install-gate.test.ts +8 -8
- package/src/scenarios/runtime-requires-shape.test.ts +7 -6
- package/src/scenarios/safefetch-behavior.test.ts +22 -21
- package/src/scenarios/safefetch-live-audit.test.ts +14 -13
- package/src/scenarios/sandbox-memory-cap.test.ts +2 -1
- package/src/scenarios/sandbox-mvp-behavior.test.ts +24 -23
- package/src/scenarios/sandbox-no-host-fs-escape.test.ts +3 -2
- package/src/scenarios/sandbox-timeout-cap.test.ts +2 -1
- package/src/scenarios/sandbox-wasm-isolation.test.ts +14 -15
- package/src/scenarios/sandbox-wasm-timeout.test.ts +5 -6
- package/src/scenarios/scheduling-capability-shape.test.ts +8 -6
- package/src/scenarios/scheduling-cron-fires-once.test.ts +8 -6
- package/src/scenarios/search-bm25-roundtrip.test.ts +8 -6
- package/src/scenarios/secret-leakage-otel-attribute.test.ts +22 -20
- package/src/scenarios/self-hosted-runner.test.ts +26 -24
- package/src/scenarios/semantic-digest-vectors.test.ts +8 -7
- package/src/scenarios/speech-synthesis-roundtrip.test.ts +9 -7
- package/src/scenarios/speech-synthesis-unadvertised.test.ts +5 -3
- package/src/scenarios/sql-injection-rejection.test.ts +8 -6
- package/src/scenarios/sql-transaction-atomicity.test.ts +10 -8
- package/src/scenarios/staleClaim.test.ts +5 -4
- package/src/scenarios/stream-modes-buffer.test.ts +8 -7
- package/src/scenarios/stream-modes-mixed.test.ts +10 -9
- package/src/scenarios/stream-modes.test.ts +12 -11
- package/src/scenarios/stream-subscribe-from-beginning.test.ts +11 -9
- package/src/scenarios/stream-text-fixture.test.ts +14 -13
- package/src/scenarios/streamReconnect.test.ts +13 -11
- package/src/scenarios/strict-behavior-gate.test.ts +9 -8
- package/src/scenarios/subrun-approval-fail-closed.test.ts +2 -2
- package/src/scenarios/subrun-approval-gate.test.ts +3 -3
- package/src/scenarios/subrun-attestation-shape.test.ts +2 -2
- package/src/scenarios/subrun-checksum-stable.test.ts +4 -4
- package/src/scenarios/subworkflow-input-mapping.test.ts +16 -14
- package/src/scenarios/subworkflow.test.ts +10 -9
- package/src/scenarios/table-cross-tenant-isolation.test.ts +8 -6
- package/src/scenarios/table-cursor-pagination.test.ts +8 -6
- package/src/scenarios/table-schema-enforcement.test.ts +7 -5
- package/src/scenarios/test-seam-unauthenticated.test.ts +2 -2
- package/src/scenarios/tool-catalog-compact-projection.test.ts +10 -8
- package/src/scenarios/tool-catalog-projection.test.ts +11 -9
- package/src/scenarios/tool-descriptor-shape.test.ts +14 -15
- package/src/scenarios/tool-hooks-authorization-fail-closed.test.ts +3 -3
- package/src/scenarios/tool-hooks-content-free.test.ts +4 -4
- package/src/scenarios/tool-hooks-failure-honesty.test.ts +4 -4
- package/src/scenarios/tool-hooks-rate-limit.test.ts +2 -2
- package/src/scenarios/tool-hooks-secret-redaction.test.ts +2 -2
- package/src/scenarios/tool-hooks-shape.test.ts +3 -3
- package/src/scenarios/tool-session-lifecycle.test.ts +14 -13
- package/src/scenarios/trigger-bridge-delivery.test.ts +14 -14
- package/src/scenarios/trigger-bridge-shape.test.ts +19 -20
- package/src/scenarios/trigger-ingestion.test.ts +19 -17
- package/src/scenarios/trigger-stream-cdc-sources.test.ts +16 -14
- package/src/scenarios/vector-knn-roundtrip.test.ts +9 -7
- package/src/scenarios/verifier-gating.test.ts +8 -6
- package/src/scenarios/version-fold.test.ts +9 -8
- package/src/scenarios/version-negotiation.test.ts +12 -11
- package/src/scenarios/voice-bargein-no-partial-leak.test.ts +8 -6
- package/src/scenarios/voice-event-payloads-shape.test.ts +10 -11
- package/src/scenarios/voice-interim-not-durable.test.ts +7 -5
- package/src/scenarios/voice-streamref-tenant-bound.test.ts +5 -3
- package/src/scenarios/voice-synthesis-streaming.test.ts +11 -9
- package/src/scenarios/voice-transcription-streaming.test.ts +8 -6
- package/src/scenarios/voice-transcription-unadvertised.test.ts +5 -3
- package/src/scenarios/wasm-pack-abi-version-rejection.test.ts +3 -2
- package/src/scenarios/wasm-pack-invoke-completed.test.ts +3 -2
- package/src/scenarios/wasm-pack-invoke-suspended.test.ts +3 -2
- package/src/scenarios/wasm-pack-load.test.ts +4 -3
- package/src/scenarios/wasm-pack-memory-cap.test.ts +5 -4
- package/src/scenarios/wasm-pack-replay-determinism.test.ts +2 -1
- package/src/scenarios/webhook-negative.test.ts +11 -9
- package/src/scenarios/webhook-receiver-adversarial.test.ts +8 -7
- package/src/scenarios/webhook-sig-algorithm.test.ts +5 -3
- package/src/scenarios/webhook-signed-delivery.test.ts +16 -15
- package/src/scenarios/webhook-tenant-isolation.test.ts +16 -14
- package/src/scenarios/workflow-chain-deferred-parameters.test.ts +28 -30
- package/src/scenarios/workflow-chain-expansion.test.ts +21 -20
- package/src/scenarios/workflow-chain-host-expansion.test.ts +21 -20
- package/src/scenarios/workflow-chain-pack-manifest-validation.test.ts +14 -12
- package/src/scenarios/workflow-chain-pack-signature-verification.test.ts +5 -4
- package/src/scenarios/workflow-chain-unresolvable-typeid.test.ts +9 -8
- package/src/scenarios/workflow-primary-output-annotation.test.ts +7 -6
- package/src/scenarios/workflow-variable-format.test.ts +24 -24
- package/src/scenarios/workload-identity-behavior.test.ts +15 -13
- package/src/scenarios/workload-identity-chain-bounds.test.ts +18 -17
- package/src/scenarios/workspace-behavior.test.ts +19 -18
- package/src/scenarios/workspace-capability-shape.test.ts +3 -2
- package/src/scenarios/workspace-cross-tenant-isolation-blackbox.test.ts +6 -5
- package/src/scenarios/workspace-cross-tenant-isolation.test.ts +7 -6
- package/src/scenarios/x-openwop-form-pack-manifest.test.ts +8 -7
- package/src/setup.ts +4 -2
- package/vitest.config.ts +5 -1
- package/api/.redocly.lint-ignore.yaml +0 -22
- package/api/asyncapi.yaml +0 -834
- package/api/grpc/openwop.proto +0 -251
- package/api/openapi.yaml +0 -2693
- package/api/redocly.yaml +0 -23
- package/schemas/README.md +0 -144
- package/schemas/a2a-task-state.schema.json +0 -78
- package/schemas/a2ui-surface-delta-frame.schema.json +0 -48
- package/schemas/agent-deployment-transition.schema.json +0 -49
- package/schemas/agent-deployment.schema.json +0 -54
- package/schemas/agent-eval-suite.schema.json +0 -140
- package/schemas/agent-inventory-response.schema.json +0 -115
- package/schemas/agent-manifest.schema.json +0 -156
- package/schemas/agent-org-chart.schema.json +0 -82
- package/schemas/agent-ref.schema.json +0 -63
- package/schemas/agent-roster-entry.schema.json +0 -81
- package/schemas/agent-roster-response.schema.json +0 -21
- package/schemas/ai-envelope.schema.json +0 -134
- package/schemas/annotation-create.schema.json +0 -37
- package/schemas/annotation.schema.json +0 -56
- package/schemas/artifact-type-pack-manifest.schema.json +0 -244
- package/schemas/audit-verify-result.schema.json +0 -90
- package/schemas/budget-policy.schema.json +0 -18
- package/schemas/capabilities.schema.json +0 -4124
- package/schemas/certification-bundle-v2.schema.json +0 -118
- package/schemas/channel-presence-payload.schema.json +0 -41
- package/schemas/channel-written-payload.schema.json +0 -55
- package/schemas/chat-card-pack-manifest.schema.json +0 -253
- package/schemas/compact-tool-descriptor.schema.json +0 -51
- package/schemas/compensation-policy.schema.json +0 -64
- package/schemas/conformance-certification-bundle.schema.json +0 -86
- package/schemas/connection-pack-manifest.schema.json +0 -353
- package/schemas/conversation-event.schema.json +0 -168
- package/schemas/conversation-turn.schema.json +0 -117
- package/schemas/core-conformance-mock-agent-config.schema.json +0 -152
- package/schemas/credential-provenance.schema.json +0 -18
- package/schemas/credential-reference.schema.json +0 -21
- package/schemas/debug-bundle.schema.json +0 -196
- package/schemas/dispatch-config.schema.json +0 -112
- package/schemas/envelopes/clarification.request.schema.json +0 -52
- package/schemas/envelopes/error.schema.json +0 -30
- package/schemas/envelopes/media.audio.schema.json +0 -38
- package/schemas/envelopes/media.file.schema.json +0 -37
- package/schemas/envelopes/media.image.schema.json +0 -33
- package/schemas/envelopes/schema.request.schema.json +0 -26
- package/schemas/envelopes/schema.response.schema.json +0 -22
- package/schemas/envelopes/ui.a2ui-surface.schema.json +0 -154
- package/schemas/error-envelope.schema.json +0 -25
- package/schemas/eval-summary.schema.json +0 -92
- package/schemas/export-bundle.schema.json +0 -66
- package/schemas/form-content-pack-manifest.schema.json +0 -243
- package/schemas/frontend-plugin-manifest.schema.json +0 -109
- package/schemas/goal.schema.json +0 -104
- package/schemas/heartbeat-evaluated.schema.json +0 -14
- package/schemas/heartbeat-state-changed.schema.json +0 -14
- package/schemas/localized-content-language-settings.schema.json +0 -26
- package/schemas/localized-content-page-response.schema.json +0 -60
- package/schemas/localized-content-page.schema.json +0 -62
- package/schemas/localized-content-section.schema.json +0 -51
- package/schemas/memory-entry.schema.json +0 -36
- package/schemas/memory-list-options.schema.json +0 -37
- package/schemas/node-pack-manifest.schema.json +0 -654
- package/schemas/orchestrator-decision.schema.json +0 -90
- package/schemas/org-chart-responsibility-view.schema.json +0 -26
- package/schemas/pack-lockfile.schema.json +0 -108
- package/schemas/prompt-kind.schema.json +0 -8
- package/schemas/prompt-pack-manifest.schema.json +0 -117
- package/schemas/prompt-ref.schema.json +0 -40
- package/schemas/prompt-template.schema.json +0 -149
- package/schemas/proposal.schema.json +0 -84
- package/schemas/registry-version-manifest.schema.json +0 -208
- package/schemas/residency.schema.json +0 -16
- package/schemas/run-ancestry-response.schema.json +0 -54
- package/schemas/run-diff-response.schema.json +0 -64
- package/schemas/run-event-payloads.schema.json +0 -4452
- package/schemas/run-event.schema.json +0 -211
- package/schemas/run-options.schema.json +0 -80
- package/schemas/run-orchestrator-decided-event.schema.json +0 -20
- package/schemas/run-snapshot.schema.json +0 -148
- package/schemas/security-advisory.schema.json +0 -109
- package/schemas/self-hosted-runner-dispatch-frame.schema.json +0 -79
- package/schemas/self-hosted-runner-registration.schema.json +0 -53
- package/schemas/self-hosted-runner-result-frame.schema.json +0 -38
- package/schemas/subject.schema.json +0 -56
- package/schemas/suspend-request.schema.json +0 -207
- package/schemas/tool-descriptor.schema.json +0 -63
- package/schemas/trigger-event.schema.json +0 -222
- package/schemas/trigger-subscription-registration.schema.json +0 -67
- package/schemas/trigger-subscription.schema.json +0 -26
- package/schemas/ui-plugin-message.schema.json +0 -90
- package/schemas/workflow-chain-pack-manifest.schema.json +0 -615
- package/schemas/workflow-definition.schema.json +0 -850
- package/schemas/workload-identity.schema.json +0 -79
- package/schemas/workspace-file-create.schema.json +0 -20
- package/schemas/workspace-file.schema.json +0 -39
package/README.md
CHANGED
|
@@ -16,6 +16,15 @@ The suite is intentionally self-contained — it does NOT depend on the referenc
|
|
|
16
16
|
|
|
17
17
|
---
|
|
18
18
|
|
|
19
|
+
|
|
20
|
+
## Suite 2.0.0 (v2 charter Phase 3; RFC 0168) — what changed for hosts
|
|
21
|
+
|
|
22
|
+
- **The contract is a peer package.** `@openwop/openwop-conformance@2.x` no longer vendors `api/` and `schemas/`; it declares `@openwop/spec-artifacts` as an exact-pinned peer dependency (install both), resolves the installed peer through Node's resolver, and refuses to start when the peer's version or `CORPUS-STAMP.json` digest differs from `dist/spec-artifacts.lock.json` (RFC 0168 §D.2). `schemas/CORPUS-STAMP.json` in this package is a copy of the peer's stamp, kept at the path hosts already read for provenance.
|
|
23
|
+
- **`--target-major 1|2`** (RFC 0168 §D.3): one package runs the scenarios for either protocol major; `scenario-majors.json` names each file's majors; the default comes from the host's root `preferredVersion` (RFC 0179), else `max(protocolVersions[])`, else 1.
|
|
24
|
+
- **`req()` is the only assertion form** (RFC 0168 §A.1): every assertion carries a requirement id; `requirements.json` lists every id; `requirement-aliases.json` maps a reworded id to its successor. `scripts/check-req-only.mjs` is the gate.
|
|
25
|
+
- **Corpus-coherence scenarios never run against a host.** They live in `src/coherence/`, run in the spec repo's CI (`scripts/check-spec-coherence.mjs`) and produce `evidence/corpus-ledger.json`; a host bundle never contains them. The `--offline` set is `fixtures-valid` only.
|
|
26
|
+
- **1.x continues on `release/1.x`** (`openwop-conformance/v1.16x.y` tags); pre-release 2.x versions publish under the npm dist-tag `next`.
|
|
27
|
+
|
|
19
28
|
## Quickstart
|
|
20
29
|
|
|
21
30
|
Two ways to run: the friendly `openwop-conformance` CLI (recommended for
|
|
@@ -103,7 +112,7 @@ Exit code is non-zero on any failed assertion. `--certify` distinguishes: `0`
|
|
|
103
112
|
|
|
104
113
|
## What's Covered
|
|
105
114
|
|
|
106
|
-
The current suite has
|
|
115
|
+
The current suite has 444 scenario files under `src/scenarios/`.
|
|
107
116
|
- 2026-09-03 (suite `1.157.0 -> 1.158.0`, gap G17): NEW `idempotency-concurrent-claim.test.ts` — drives the new `host-sample-test-seams.md` §25 concurrent duplicate-delivery seam for the RFC 0150 §B / `idempotency.md` §"Concurrent duplicates (Layer 2)" atomic-claim MUST, which is unconditional and had no witness of any kind. Asserts every executor mints the SAME `logicalInvocationId` **before** asserting `delivered === 1` — without the identity check a host passes by minting different ids and never colliding, one effect because nothing raced. Not profile-gated and so not opt-out-able (the obligation is unconditional); an unmounted seam records `blocked`, which is not certifiable. Graduates `layer2-invocation-claim-atomic` reference-impl -> protocol.
|
|
108
117
|
- 2026-08-19 (suite `1.137.0 → 1.138.0`): NEW `durability-poison-exhaustion.test.ts` — RFC 0158 §C.8, the FIRST row of that RFC's conformance table to land. Asserts what `failure-path.test.ts` cannot: not just that deterministically failing work reaches terminal, but that attempts STOP — counted on the log, re-counted after a scaled quiet window, asserted unchanged. A host still redelivering records more. Seam-gated on the existing event-log seam (`blocked` = unobservable, not unmet) and outside every profile floor.
|
|
109
118
|
- 2026-08-19 (suite `1.136.15 → 1.137.0`): NEW `replay-fanout-suppression.test.ts` — capability-gated on `webhooks.supported`, **outside every profile floor**; witnesses `replay.md` §"Host-initiated fan-out is an external effect", which was the largest normative MUST NOT on the replay surface with no scenario and no SECURITY invariant. Three legs in ONE `it` against ONE receiver and ONE subscription — a positive control, the MUST NOT, and a `branch` boundary leg — because "no delivery arrived" passes identically when delivery never worked, so absence is asserted only after presence is proven on that exact wiring. A host with an SSRF guard correctly refuses the loopback receiver and records `blocked`: **unobservable, not unmet.**
|
|
@@ -448,7 +457,7 @@ Server-required (added in 1.7.0):
|
|
|
448
457
|
| ------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
449
458
|
| **Redaction** | [`capabilities.md`](../spec/v1/capabilities.md) §"Secrets" + NFR-7 + §"aiProviders" | Vendor-neutral assertions that the server doesn't leak secret material. Three scenario groups: (a) discovery shape contract — `secrets` + `aiProviders` advertisements are well-formed regardless of `secrets.supported`; when `supported === true`, scopes MUST be non-empty + `resolution === 'host-managed'`; `byok ⊆ supported`. (b) bearer-token redaction — invalid Bearer canary in `Authorization` header is not echoed in the 401 response body. (c) credentialRef echo control — gated on `secrets.supported === true`; canary planted in `configurable.ai.credentialRef` MUST NOT appear in any RunEvent payload (poll-based capture; transport-agnostic). Uses runtime-built canary fixtures (`lib/canaries.ts`) that defeat static secret scanners. 6 scenarios. |
|
|
450
459
|
|
|
451
|
-
Current source tree:
|
|
460
|
+
Current source tree: 444 scenario files. Use [`coverage.md`](./coverage.md) for current grade/gap tracking.
|
|
452
461
|
|
|
453
462
|
## Remaining Gaps
|
|
454
463
|
|
package/dist/cli.js
CHANGED
|
@@ -57,6 +57,7 @@ function parseArgs(argv) {
|
|
|
57
57
|
// `--bundle-version 1` through the RFC 0148 migration window (ends
|
|
58
58
|
// 2026-11-10) and is removed at v2.0 (spec/v1/deprecations.json).
|
|
59
59
|
let bundleVersion = '2';
|
|
60
|
+
let targetMajor;
|
|
60
61
|
let maxWorkers = parseMaxWorkers(process.env.OPENWOP_MAX_WORKERS, 'OPENWOP_MAX_WORKERS');
|
|
61
62
|
for (let i = 0; i < argv.length; i++) {
|
|
62
63
|
const arg = argv[i] ?? '';
|
|
@@ -88,6 +89,15 @@ function parseArgs(argv) {
|
|
|
88
89
|
case '--api-key':
|
|
89
90
|
apiKey = nextValue();
|
|
90
91
|
break;
|
|
92
|
+
case '--target-major': {
|
|
93
|
+
const v = argv[++i];
|
|
94
|
+
if (v !== '1' && v !== '2') {
|
|
95
|
+
process.stderr.write(`openwop-conformance: --target-major must be 1 or 2 (got ${String(v)})\n`);
|
|
96
|
+
process.exit(2);
|
|
97
|
+
}
|
|
98
|
+
targetMajor = v === '2' ? 2 : 1;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
91
101
|
case '--filter':
|
|
92
102
|
filter = nextValue();
|
|
93
103
|
break;
|
|
@@ -133,6 +143,7 @@ function parseArgs(argv) {
|
|
|
133
143
|
implVersion,
|
|
134
144
|
certify,
|
|
135
145
|
bundleVersion,
|
|
146
|
+
targetMajor,
|
|
136
147
|
maxWorkers,
|
|
137
148
|
};
|
|
138
149
|
}
|
|
@@ -169,6 +180,9 @@ Implementation labels (cosmetic — surface in failure messages):
|
|
|
169
180
|
--impl-version <version> Implementation version (env: OPENWOP_IMPLEMENTATION_VERSION)
|
|
170
181
|
|
|
171
182
|
Certification (RFC 0089):
|
|
183
|
+
--target-major <1|2> Suite 2.0.0 (RFC 0168 §D.3): run the scenarios for this protocol
|
|
184
|
+
major. Default: the host's preferredVersion (RFC 0179), else
|
|
185
|
+
max(protocolVersions[]), else 1. Selection is scenario-majors.json.
|
|
172
186
|
--bundle-version <1|2> Certification bundle format. Default 2 (corrected 2026-09-03, RFC 0168 §E.4; the text said 1 while the code set 2). Version 2 (RFC 0148
|
|
173
187
|
§C) records per-requirement DISPOSITIONS instead of pass/fail/skip
|
|
174
188
|
file lists, so "we could not check" stops being indistinguishable
|
|
@@ -272,6 +286,34 @@ function scenarioStatesFromReport(report) {
|
|
|
272
286
|
return states;
|
|
273
287
|
}
|
|
274
288
|
/** Generate + validate + write an RFC 0089 conformance certification bundle. */
|
|
289
|
+
/**
|
|
290
|
+
* Suite 2.0.0 — resolve the target major (RFC 0168 §D.3 / RFC 0179): the flag,
|
|
291
|
+
* else the host's root `preferredVersion`, else max(protocolVersions[]), else 1.
|
|
292
|
+
* Returns the major and the scenario files that target it (scenario-majors.json).
|
|
293
|
+
*/
|
|
294
|
+
async function resolveTargetMajor(args, baseUrl, apiKey, conformanceRoot) {
|
|
295
|
+
let major = args.targetMajor;
|
|
296
|
+
let source = 'flag';
|
|
297
|
+
if (major === undefined && baseUrl) {
|
|
298
|
+
try {
|
|
299
|
+
const res = await fetch(`${baseUrl.replace(/\/$/, '')}/.well-known/openwop`, { headers: apiKey ? { authorization: `Bearer ${apiKey}` } : {} });
|
|
300
|
+
const doc = (await res.json());
|
|
301
|
+
const pv = doc.preferredVersion ?? (doc.protocolVersions ?? []).map((v) => v).sort((a, b) => Number(b.split('.')[0]) - Number(a.split('.')[0]))[0];
|
|
302
|
+
if (pv) {
|
|
303
|
+
major = Number(pv.split('.')[0]) >= 2 ? 2 : 1;
|
|
304
|
+
source = doc.preferredVersion ? 'preferredVersion' : 'max(protocolVersions[])';
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
catch { /* unreachable host: the default below; the run itself will report the failure */ }
|
|
308
|
+
}
|
|
309
|
+
if (major === undefined) {
|
|
310
|
+
major = 1;
|
|
311
|
+
source = 'default';
|
|
312
|
+
}
|
|
313
|
+
const manifest = JSON.parse(readFileSync(resolvePath(conformanceRoot, 'scenario-majors.json'), 'utf8'));
|
|
314
|
+
const files = Object.entries(manifest.majors).filter(([, m]) => m.includes(major)).map(([f]) => `src/scenarios/${f}`);
|
|
315
|
+
return { major, files, source };
|
|
316
|
+
}
|
|
275
317
|
async function runCertify(args, baseUrl, apiKey) {
|
|
276
318
|
const outPath = args.certify;
|
|
277
319
|
if (outPath === undefined)
|
|
@@ -312,6 +354,9 @@ async function runCertify(args, baseUrl, apiKey) {
|
|
|
312
354
|
env.OPENWOP_IMPLEMENTATION_NAME = args.impl;
|
|
313
355
|
if (args.implVersion)
|
|
314
356
|
env.OPENWOP_IMPLEMENTATION_VERSION = args.implVersion;
|
|
357
|
+
const target = await resolveTargetMajor(args, baseUrl, apiKey, conformanceRoot);
|
|
358
|
+
env.OPENWOP_TARGET_MAJOR = String(target.major);
|
|
359
|
+
process.stderr.write(`openwop-conformance --certify: target major ${target.major} (${target.source}); ${target.files.length} scenario file(s)\n`);
|
|
315
360
|
const vitestArgs = [
|
|
316
361
|
'vitest',
|
|
317
362
|
'run',
|
|
@@ -320,6 +365,8 @@ async function runCertify(args, baseUrl, apiKey) {
|
|
|
320
365
|
'--reporter=json',
|
|
321
366
|
`--outputFile=${reportFile}`,
|
|
322
367
|
...maxWorkersArgs(args.maxWorkers),
|
|
368
|
+
...(args.filter ? ['--testNamePattern', args.filter] : []),
|
|
369
|
+
...target.files,
|
|
323
370
|
];
|
|
324
371
|
const runResult = spawnSync('npx', vitestArgs, { cwd: conformanceRoot, env, stdio: 'inherit' });
|
|
325
372
|
if (runResult.error) {
|
|
@@ -420,7 +467,7 @@ async function runCertify(args, baseUrl, apiKey) {
|
|
|
420
467
|
// the discovery it saw. Two runs against differently-configured hosts are
|
|
421
468
|
// different evidence, and this is what says so.
|
|
422
469
|
const configSha = createHash('sha256')
|
|
423
|
-
.update(`${
|
|
470
|
+
.update(`${baseUrl}\n${sha256}\n${process.env['OPENWOP_REQUIRE_BEHAVIOR'] ?? ''}`, 'utf8')
|
|
424
471
|
.digest('hex');
|
|
425
472
|
// Rows come from the ledger (S6). A file that recorded nothing is
|
|
426
473
|
// `blocked` — unclassified — and, if it sits on a claimed floor, rejected above.
|
|
@@ -571,6 +618,12 @@ async function main() {
|
|
|
571
618
|
// ancestor config (e.g., a parent monorepo's vite.config.ts) when
|
|
572
619
|
// the conformance package is used as a workspace member.
|
|
573
620
|
const vitestArgs = ['run', '--config', resolvePath(conformanceRoot, 'vitest.config.ts')];
|
|
621
|
+
const target = await resolveTargetMajor(args, env.OPENWOP_BASE_URL, env.OPENWOP_API_KEY, conformanceRoot);
|
|
622
|
+
env.OPENWOP_TARGET_MAJOR = String(target.major);
|
|
623
|
+
if (!args.offline) {
|
|
624
|
+
process.stderr.write(`openwop-conformance: target major ${target.major} (${target.source}); ${target.files.length} scenario file(s)\n`);
|
|
625
|
+
vitestArgs.push(...target.files);
|
|
626
|
+
}
|
|
574
627
|
if (args.offline) {
|
|
575
628
|
// Suite 1.154.0: the offline set is a DECLARED property of the package —
|
|
576
629
|
// exactly the server-free scenarios that ship in the tarball and run in
|
package/dist/lib/paths.js
CHANGED
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
*/
|
|
36
36
|
import { existsSync } from 'node:fs';
|
|
37
37
|
import { fileURLToPath } from 'node:url';
|
|
38
|
+
import { createRequire } from 'node:module';
|
|
38
39
|
import { dirname, join, resolve as pathResolve } from 'node:path';
|
|
39
40
|
// `dirname(fileURLToPath(import.meta.url))` for an ESM module compiled or
|
|
40
41
|
// run from `src/lib/paths.ts` returns `<pkg>/src/lib/`. The conformance
|
|
@@ -43,7 +44,22 @@ import { dirname, join, resolve as pathResolve } from 'node:path';
|
|
|
43
44
|
// identical between the two; only the parent of `<pkg>` differs.
|
|
44
45
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
45
46
|
const PKG_ROOT = pathResolve(HERE, '..', '..');
|
|
46
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Suite 2.0.0 (RFC 0168 §D.2): in the published layout the CONTRACT (api/ and
|
|
49
|
+
* schemas/) is the `@openwop/spec-artifacts` peer package, not files vendored
|
|
50
|
+
* into this tarball. Resolve its root through Node's resolver from this package
|
|
51
|
+
* so the host's installed peer is what the suite validates against.
|
|
52
|
+
*/
|
|
53
|
+
function resolvePeerRoot() {
|
|
54
|
+
try {
|
|
55
|
+
const req = createRequire(join(PKG_ROOT, 'package.json'));
|
|
56
|
+
return dirname(req.resolve('@openwop/spec-artifacts/package.json'));
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
function resolveFromRoot(root, layout, contractRoot = root) {
|
|
47
63
|
// Two on-disk shapes for the layout root:
|
|
48
64
|
// - Repo: <root>/schemas, <root>/api, <root>/conformance/fixtures,
|
|
49
65
|
// <root>/conformance/{fixtures.md,coverage.md}, <root>/spec/v1/*.md
|
|
@@ -52,8 +68,8 @@ function resolveFromRoot(root, layout) {
|
|
|
52
68
|
// <root>/fixtures.md (when bundled), no spec/v1.
|
|
53
69
|
// Probe by checking whether `schemas/` lives at the conformance pkg root
|
|
54
70
|
// (vendored) vs one level up (repo).
|
|
55
|
-
const schemasDir = join(
|
|
56
|
-
const apiDir = join(
|
|
71
|
+
const schemasDir = join(contractRoot, 'schemas');
|
|
72
|
+
const apiDir = join(contractRoot, 'api');
|
|
57
73
|
const repoFixturesDir = join(root, 'conformance', 'fixtures');
|
|
58
74
|
const vendoredFixturesDir = join(root, 'fixtures');
|
|
59
75
|
const fixturesDir = existsSync(repoFixturesDir) ? repoFixturesDir : vendoredFixturesDir;
|
|
@@ -131,7 +147,13 @@ function resolveLayout() {
|
|
|
131
147
|
if (parentHasSchemas) {
|
|
132
148
|
return resolveFromRoot(parent, 'repo');
|
|
133
149
|
}
|
|
150
|
+
const peer = resolvePeerRoot();
|
|
151
|
+
if (peer) {
|
|
152
|
+
return resolveFromRoot(PKG_ROOT, 'published', peer);
|
|
153
|
+
}
|
|
134
154
|
if (pkgHasSchemas) {
|
|
155
|
+
// A pre-2.0 tarball layout (schemas vendored in-package); kept so an old
|
|
156
|
+
// layout still resolves, but the 2.x stamp check refuses to run without the peer.
|
|
135
157
|
return resolveFromRoot(PKG_ROOT, 'published');
|
|
136
158
|
}
|
|
137
159
|
// Neither — return the published-style resolution rooted at PKG_ROOT
|
|
@@ -24,6 +24,20 @@
|
|
|
24
24
|
* `~3`, … (vitest allows duplicate titles; the ledger does not allow duplicate
|
|
25
25
|
* ids). A scenario MAY override the derived id for the current test with
|
|
26
26
|
* `req()` when it wants a hand-authored, registry-listed id.
|
|
27
|
+
*
|
|
28
|
+
* requireExplicitIds (suite 2.0.0, RFC 0168 §A.1): from 2.0.0 `req(id, section,
|
|
29
|
+
* requirement)` is the ONLY assertion-message form in `src/scenarios` and
|
|
30
|
+
* `src/coherence` — `driver.describe(section, requirement)` is gone from every
|
|
31
|
+
* scenario, and `scripts/check-req-only.mjs` (root) fails the gate when a
|
|
32
|
+
* scenario reintroduces it, when an `expect` carries a bare string message,
|
|
33
|
+
* when an `it` body returns without `softSkip` / `seamAbsent`, or when two
|
|
34
|
+
* `it`s in one file share an explicit id. Every `it` therefore names the
|
|
35
|
+
* requirement it witnesses on the wire; the title-derived allocator below is
|
|
36
|
+
* the fallback for an `it` that makes no cited assertion at all. The ids the
|
|
37
|
+
* 2.0.0 sweep wrote are exactly the ids the allocator derived in 1.x (same
|
|
38
|
+
* stem + slug + `~n` order), so no bundle id changed at the cut-over; an `it`
|
|
39
|
+
* with an interpolated title carries a hand-minted id from the static parts of
|
|
40
|
+
* its title, unique within the file.
|
|
27
41
|
*/
|
|
28
42
|
export const IT_ID_PREFIX = 'openwop.it.';
|
|
29
43
|
export const IT_ID_GRAMMAR = /^openwop\.it\.[a-z0-9]+(?:-[a-z0-9]+)*\.[a-z0-9]+(?:-[a-z0-9]+)*(?:~[2-9][0-9]*)?$/;
|
|
@@ -64,7 +78,12 @@ export class ItIdAllocator {
|
|
|
64
78
|
seen = new Map();
|
|
65
79
|
allocate(scenarioFile, title) {
|
|
66
80
|
const base = itRequirementId(scenarioFile, title);
|
|
67
|
-
|
|
81
|
+
let n = (this.seen.get(base) ?? 0) + 1;
|
|
82
|
+
// An id a sibling `it` already claimed through `req()` never reached this
|
|
83
|
+
// allocator, so a same-titled `it` that cites nothing must skip past it —
|
|
84
|
+
// otherwise the first explicit `exists` and the derived `exists` collide.
|
|
85
|
+
while (claimedExplicit.has(n === 1 ? base : `${base}~${n}`))
|
|
86
|
+
n++;
|
|
68
87
|
this.seen.set(base, n);
|
|
69
88
|
return n === 1 ? base : `${base}~${n}`;
|
|
70
89
|
}
|
|
@@ -76,21 +95,32 @@ export class ItIdAllocator {
|
|
|
76
95
|
// Explicit override for the current test.
|
|
77
96
|
// ---------------------------------------------------------------------------
|
|
78
97
|
let explicitId = null;
|
|
98
|
+
/** Every id handed to `req()` in this worker — consulted by `ItIdAllocator`. */
|
|
99
|
+
const claimedExplicit = new Set();
|
|
79
100
|
/**
|
|
80
101
|
* Attach a hand-authored requirement id to the CURRENT test. The per-`it`
|
|
81
102
|
* ledger row for this test is recorded under `id` instead of the derived
|
|
82
|
-
* title id. Returns the
|
|
83
|
-
*
|
|
103
|
+
* title id. Returns the SAME message shape `driver.describe` returns —
|
|
104
|
+
* `[<impl>@<version>] <section>: <requirement>` — so a failure still names
|
|
105
|
+
* the implementation under test:
|
|
84
106
|
*
|
|
85
107
|
* expect(x, req('openwop.auth.subject-link.leaver-deny', 'auth-profiles.md §Subject linking', 'deactivation MUST deny')).toBe(true)
|
|
86
108
|
*
|
|
109
|
+
* The implementation label is read straight from `OPENWOP_IMPLEMENTATION_NAME`
|
|
110
|
+
* / `OPENWOP_IMPLEMENTATION_VERSION` with the defaults `env.ts` uses (`unknown`)
|
|
111
|
+
* rather than through `loadEnv()`, so a suite self-test can call `req()`
|
|
112
|
+
* without `OPENWOP_BASE_URL` set.
|
|
113
|
+
*
|
|
87
114
|
* The id MUST be listed in `conformance/requirements.json` (the generator
|
|
88
115
|
* collects `req(` first-argument literals); an unlisted id fails the registry
|
|
89
116
|
* check, so a hand id cannot drift from the registry silently.
|
|
90
117
|
*/
|
|
91
118
|
export function req(id, specSection, requirement) {
|
|
92
119
|
explicitId = id;
|
|
93
|
-
|
|
120
|
+
claimedExplicit.add(id);
|
|
121
|
+
const impl = process.env['OPENWOP_IMPLEMENTATION_NAME']?.trim() ?? 'unknown';
|
|
122
|
+
const version = process.env['OPENWOP_IMPLEMENTATION_VERSION']?.trim() ?? 'unknown';
|
|
123
|
+
return `[${impl}@${version}] ${specSection}: ${requirement}`;
|
|
94
124
|
}
|
|
95
125
|
/** setup.ts reads and clears the override after each test. */
|
|
96
126
|
export function takeExplicitRequirementId() {
|
|
@@ -110,6 +110,7 @@ export function resolveFileRecord(states, gateReason, assertionCount, noted, spe
|
|
|
110
110
|
// CERTIFIABLE, so these rows stop counting against a host that cannot affect
|
|
111
111
|
// them. See lib/spec-coherence.ts for why not a new disposition value.
|
|
112
112
|
if (specCoherenceFile !== undefined
|
|
113
|
+
&& process.env.OPENWOP_CORPUS_GATE !== '1' // suite 2.0.0: under the corpus gate the coherence scenario IS the subject
|
|
113
114
|
&& SPEC_COHERENCE_SCENARIOS.has(specCoherenceFile)
|
|
114
115
|
&& !states.includes('fail')
|
|
115
116
|
&& assertionCount === 0) {
|
|
@@ -79,38 +79,19 @@
|
|
|
79
79
|
* disjoint and jointly exhaustive over the `V1_DIR`-gated files, and a comment
|
|
80
80
|
* is no longer the only place the exclusion reason lives.
|
|
81
81
|
*/
|
|
82
|
-
/**
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
'error-envelope-canonical-shape.test.ts',
|
|
96
|
-
'event-codemap-complete.test.ts',
|
|
97
|
-
'form-content-packs.test.ts',
|
|
98
|
-
'multi-region-effect-vocabulary.test.ts',
|
|
99
|
-
'normative-example-extraction.test.ts',
|
|
100
|
-
'openapi-asyncapi-sdk-parity.test.ts',
|
|
101
|
-
'pack-manifest-extensions.test.ts',
|
|
102
|
-
'protocol-version-grammar.test.ts',
|
|
103
|
-
'registry-declarative-kinds.test.ts',
|
|
104
|
-
'rfc-0147-self-audit.test.ts',
|
|
105
|
-
'rfc-lifecycle-coherence.test.ts',
|
|
106
|
-
'semantic-digest-v2.test.ts',
|
|
107
|
-
'spec-corpus-validity.test.ts',
|
|
108
|
-
'spec-section-citations.test.ts',
|
|
109
|
-
'tool-result-trust-monotone.test.ts',
|
|
110
|
-
'versioned-composition-profiles.test.ts',
|
|
111
|
-
'workflow-chain-internal-flag.test.ts',
|
|
112
|
-
'workload-identity-profile.test.ts',
|
|
113
|
-
]);
|
|
82
|
+
/**
|
|
83
|
+
* Scenarios whose subject is the corpus. Suite 2.0.0 (RFC 0168 §D.1): they
|
|
84
|
+
* live in `src/coherence/`, not `src/scenarios/`, and the set is the DIRECTORY
|
|
85
|
+
* LISTING — one source of truth instead of four (this list, the package.json
|
|
86
|
+
* negations, spec-coherence-scenarios.json and the registry self-test used to
|
|
87
|
+
* each carry a copy). They run in the spec repo's CI (scripts/check-spec-coherence.mjs)
|
|
88
|
+
* and never enter a host bundle; the published tarball excludes the directory.
|
|
89
|
+
*/
|
|
90
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
91
|
+
import { fileURLToPath } from 'node:url';
|
|
92
|
+
import { dirname, join } from 'node:path';
|
|
93
|
+
const COHERENCE_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'coherence');
|
|
94
|
+
export const SPEC_COHERENCE_SCENARIOS = new Set(existsSync(COHERENCE_DIR) ? readdirSync(COHERENCE_DIR).filter((f) => f.endsWith('.test.ts')).sort() : []);
|
|
114
95
|
/**
|
|
115
96
|
* Scenarios that gate on `V1_DIR` **and** drive the host, so their `blocked` is
|
|
116
97
|
* honest: advertised behaviour a missing dependency prevented exercising.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openwop/openwop-conformance",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-rc.0",
|
|
4
4
|
"description": "Production-ready black-box conformance suite for OpenWOP v1.0 compliant servers.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"coverage.md",
|
|
21
21
|
"requirements.json",
|
|
22
22
|
"requirement-aliases.json",
|
|
23
|
-
"
|
|
23
|
+
"scenario-majors.json",
|
|
24
24
|
"schemas",
|
|
25
25
|
"vectors",
|
|
26
26
|
"vitest.config.ts",
|
|
@@ -28,35 +28,7 @@
|
|
|
28
28
|
"CHANGELOG.md",
|
|
29
29
|
"LICENSE",
|
|
30
30
|
"!src/lib/*.test.ts",
|
|
31
|
-
"!src/
|
|
32
|
-
"!src/scenarios/artifact-type-legacy-ids.test.ts",
|
|
33
|
-
"!src/scenarios/capability-example-root-layout.test.ts",
|
|
34
|
-
"!src/scenarios/certification-floor-enforcement.test.ts",
|
|
35
|
-
"!src/scenarios/chain-subchain-unsupported-refused.test.ts",
|
|
36
|
-
"!src/scenarios/compensation-profile.test.ts",
|
|
37
|
-
"!src/scenarios/core-manifest-and-extension-registry.test.ts",
|
|
38
|
-
"!src/scenarios/discovery-canonical-family-no-shadow.test.ts",
|
|
39
|
-
"!src/scenarios/edge-condition-truthy-falsy.test.ts",
|
|
40
|
-
"!src/scenarios/effect-identity-composition.test.ts",
|
|
41
|
-
"!src/scenarios/effect-identity-cross-scope.test.ts",
|
|
42
|
-
"!src/scenarios/error-envelope-canonical-shape.test.ts",
|
|
43
|
-
"!src/scenarios/event-codemap-complete.test.ts",
|
|
44
|
-
"!src/scenarios/form-content-packs.test.ts",
|
|
45
|
-
"!src/scenarios/multi-region-effect-vocabulary.test.ts",
|
|
46
|
-
"!src/scenarios/normative-example-extraction.test.ts",
|
|
47
|
-
"!src/scenarios/openapi-asyncapi-sdk-parity.test.ts",
|
|
48
|
-
"!src/scenarios/pack-manifest-extensions.test.ts",
|
|
49
|
-
"!src/scenarios/protocol-version-grammar.test.ts",
|
|
50
|
-
"!src/scenarios/registry-declarative-kinds.test.ts",
|
|
51
|
-
"!src/scenarios/rfc-0147-self-audit.test.ts",
|
|
52
|
-
"!src/scenarios/rfc-lifecycle-coherence.test.ts",
|
|
53
|
-
"!src/scenarios/semantic-digest-v2.test.ts",
|
|
54
|
-
"!src/scenarios/spec-corpus-validity.test.ts",
|
|
55
|
-
"!src/scenarios/spec-section-citations.test.ts",
|
|
56
|
-
"!src/scenarios/tool-result-trust-monotone.test.ts",
|
|
57
|
-
"!src/scenarios/versioned-composition-profiles.test.ts",
|
|
58
|
-
"!src/scenarios/workflow-chain-internal-flag.test.ts",
|
|
59
|
-
"!src/scenarios/workload-identity-profile.test.ts"
|
|
31
|
+
"!src/coherence"
|
|
60
32
|
],
|
|
61
33
|
"scripts": {
|
|
62
34
|
"test": "vitest run",
|
|
@@ -66,7 +38,9 @@
|
|
|
66
38
|
"build:cli": "tsc -p tsconfig.build.json && chmod +x dist/cli.js",
|
|
67
39
|
"cli": "tsx src/cli.ts",
|
|
68
40
|
"prepack": "bash scripts/pack-vendor.sh",
|
|
69
|
-
"postpack": "rm -rf
|
|
41
|
+
"postpack": "rm -rf schemas",
|
|
42
|
+
"test:coherence": "vitest run --config vitest.coherence.config.ts",
|
|
43
|
+
"test:self": "vitest run --config vitest.selftest.config.ts"
|
|
70
44
|
},
|
|
71
45
|
"engines": {
|
|
72
46
|
"node": ">=20"
|
|
@@ -78,6 +52,10 @@
|
|
|
78
52
|
},
|
|
79
53
|
"devDependencies": {
|
|
80
54
|
"typescript": "^5.6.0",
|
|
81
|
-
"@types/node": "^22.0.0"
|
|
55
|
+
"@types/node": "^22.0.0",
|
|
56
|
+
"@openwop/spec-artifacts": "file:../spec-artifacts"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"@openwop/spec-artifacts": "2.0.0-rc.0"
|
|
82
60
|
}
|
|
83
61
|
}
|