@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
|
@@ -36,6 +36,8 @@
|
|
|
36
36
|
import { describe, it, expect } from 'vitest';
|
|
37
37
|
import { driver } from '../lib/driver.js';
|
|
38
38
|
import { capabilityFamily } from '../lib/discovery-capabilities.js';
|
|
39
|
+
import { req } from '../lib/requirement-ids.js';
|
|
40
|
+
import { softSkip } from '../lib/soft-skip.js';
|
|
39
41
|
|
|
40
42
|
const HTTP_SKIP = !process.env.OPENWOP_BASE_URL;
|
|
41
43
|
|
|
@@ -97,13 +99,13 @@ const CANONICAL_MARKER = `[REDACTED:${CANARY_SECRET_ID}]`;
|
|
|
97
99
|
describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: advertisement shape (RFC 0030 §E)', () => {
|
|
98
100
|
it('hosts advertising envelope reasoning + BYOK honor SR-1 carry-forward for the reasoning field', async () => {
|
|
99
101
|
const d = await readDiscovery();
|
|
100
|
-
if (d === null) return;
|
|
102
|
+
if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
|
|
101
103
|
const reasoning = capabilityFamily<{ reasoning?: Record<string, unknown>; tierOneSubsetCompliance?: unknown; reliability?: { completion?: Record<string, unknown> } & Record<string, unknown> }>(d, 'envelopes')?.reasoning?.supported;
|
|
102
104
|
const secrets = capabilityFamily<{ supported?: unknown }>(d, 'secrets')?.supported;
|
|
103
|
-
if (reasoning !== true || secrets !== true) return; // soft-skip when either is absent
|
|
105
|
+
if (reasoning !== true || secrets !== true) return softSkip('blocked', 'precondition not met — `reasoning !== true || secrets !== true` returned early (soft-skip when either is absent) (seam, prior step, or fixture unavailable)'); // soft-skip when either is absent
|
|
104
106
|
// The contract is invariant-based, not capability-flag-based — the
|
|
105
107
|
// advertisement-shape check here just confirms both surfaces are claimed.
|
|
106
|
-
expect(true).toBe(true);
|
|
108
|
+
expect(true, req('openwop.it.envelope-reasoning-secret-redaction.hosts-advertising-envelope-reasoning-byok-honor-sr-1-carry-forward-for-the-reaso', 'RFC 0030 §E', 'hosts advertising envelope reasoning + BYOK honor SR-1 carry-forward for the reasoning field')).toBe(true);
|
|
107
109
|
});
|
|
108
110
|
});
|
|
109
111
|
|
|
@@ -124,22 +126,22 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: BYOK redaction
|
|
|
124
126
|
},
|
|
125
127
|
{ byokCanaries: CANARIES },
|
|
126
128
|
);
|
|
127
|
-
if (r.status === 404) return; // host doesn't expose the seam
|
|
128
|
-
expect(r.body.status, 'envelope MUST be accepted; redaction is a post-validation pass').toBe('accepted');
|
|
129
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (host doesn\'t expose the seam) (seam, prior step, or fixture unavailable)'); // host doesn't expose the seam
|
|
130
|
+
expect(r.body.status, req('openwop.it.envelope-reasoning-secret-redaction.canary-in-reasoning-substituted-with-canonical-redacted-secretid-marker-per-agen', 'ai-envelope.md §"Redaction (SR-1 carry-forward)"', 'envelope MUST be accepted; redaction is a post-validation pass')).toBe('accepted');
|
|
129
131
|
expect(
|
|
130
132
|
r.body.redactionCount,
|
|
131
|
-
'RFC 0030 §E: redactionCount MUST be > 0 when a canary appears in `reasoning`',
|
|
133
|
+
req('openwop.it.envelope-reasoning-secret-redaction.canary-in-reasoning-substituted-with-canonical-redacted-secretid-marker-per-agen', 'ai-envelope.md §"Redaction (SR-1 carry-forward)"', 'RFC 0030 §E: redactionCount MUST be > 0 when a canary appears in `reasoning`'),
|
|
132
134
|
).toBeGreaterThan(0);
|
|
133
135
|
expect(
|
|
134
136
|
JSON.stringify(r.body.redactedPayload).includes(CANARY_VALUE),
|
|
135
|
-
|
|
137
|
+
req('openwop.it.envelope-reasoning-secret-redaction.canary-in-reasoning-substituted-with-canonical-redacted-secretid-marker-per-agen',
|
|
136
138
|
'ai-envelope.md §"Redaction (SR-1 carry-forward)"',
|
|
137
139
|
'canary plaintext MUST NOT remain anywhere in the redacted view — `reasoning` field included',
|
|
138
140
|
),
|
|
139
141
|
).toBe(false);
|
|
140
142
|
expect(
|
|
141
143
|
JSON.stringify(r.body.redactedPayload),
|
|
142
|
-
|
|
144
|
+
req('openwop.it.envelope-reasoning-secret-redaction.canary-in-reasoning-substituted-with-canonical-redacted-secretid-marker-per-agen',
|
|
143
145
|
'agent-memory.md §SR-1 line 66',
|
|
144
146
|
'persisted entry MUST carry [REDACTED:<secretId>] in place of the plaintext',
|
|
145
147
|
),
|
|
@@ -162,15 +164,15 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: BYOK redaction
|
|
|
162
164
|
},
|
|
163
165
|
{ byokCanaries: CANARIES },
|
|
164
166
|
);
|
|
165
|
-
if (r.status === 404) return;
|
|
167
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
166
168
|
expect(r.body.status).toBe('accepted');
|
|
167
169
|
expect(
|
|
168
170
|
JSON.stringify(r.body.redactedPayload).includes(CANARY_VALUE),
|
|
169
|
-
'no canary plaintext remnant anywhere — `reasoning` + `message` both walked recursively',
|
|
171
|
+
req('openwop.it.envelope-reasoning-secret-redaction.canary-in-reasoning-and-another-payload-field-both-occurrences-scrubbed-with-sin', 'RFC 0030 §E', 'no canary plaintext remnant anywhere — `reasoning` + `message` both walked recursively'),
|
|
170
172
|
).toBe(false);
|
|
171
173
|
expect(
|
|
172
174
|
r.body.redactionCount,
|
|
173
|
-
'recursive walk substitutes once per occurrence; 2 occurrences = redactionCount: 2',
|
|
175
|
+
req('openwop.it.envelope-reasoning-secret-redaction.canary-in-reasoning-and-another-payload-field-both-occurrences-scrubbed-with-sin', 'RFC 0030 §E', 'recursive walk substitutes once per occurrence; 2 occurrences = redactionCount: 2'),
|
|
174
176
|
).toBe(2);
|
|
175
177
|
});
|
|
176
178
|
|
|
@@ -190,13 +192,13 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: BYOK redaction
|
|
|
190
192
|
},
|
|
191
193
|
{ byokCanaries: CANARIES }, // canary in fixture, but NOT in payload
|
|
192
194
|
);
|
|
193
|
-
if (r.status === 404) return;
|
|
195
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
194
196
|
expect(r.body.status).toBe('accepted');
|
|
195
|
-
expect(r.body.redactionCount, 'no canary occurrence → redactionCount: 0').toBe(0);
|
|
197
|
+
expect(r.body.redactionCount, req('openwop.it.envelope-reasoning-secret-redaction.absent-canary-in-reasoning-reasoning-passes-through-unchanged-no-false-positive', 'RFC 0030 §E', 'no canary occurrence → redactionCount: 0')).toBe(0);
|
|
196
198
|
const payload = (r.body.redactedPayload ?? {}) as { reasoning?: string };
|
|
197
199
|
expect(
|
|
198
200
|
payload.reasoning,
|
|
199
|
-
'reasoning field MUST pass through unchanged when no canary substring matches',
|
|
201
|
+
req('openwop.it.envelope-reasoning-secret-redaction.absent-canary-in-reasoning-reasoning-passes-through-unchanged-no-false-positive', 'RFC 0030 §E', 'reasoning field MUST pass through unchanged when no canary substring matches'),
|
|
200
202
|
).toBe('The input was empty; I declined to fabricate a response.');
|
|
201
203
|
});
|
|
202
204
|
|
|
@@ -215,8 +217,8 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: BYOK redaction
|
|
|
215
217
|
},
|
|
216
218
|
{ byokCanaries: CANARIES },
|
|
217
219
|
);
|
|
218
|
-
if (r.status === 404) return;
|
|
219
|
-
expect(r.body.status).toBe('accepted');
|
|
220
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
221
|
+
expect(r.body.status, req('openwop.it.envelope-reasoning-secret-redaction.canary-in-clarification-request-reasoning-universal-kind-with-reasoning-property', 'RFC 0030 §E', 'canary in `clarification.request.reasoning` (universal kind with reasoning property)')).toBe('accepted');
|
|
220
222
|
expect(JSON.stringify(r.body.redactedPayload).includes(CANARY_VALUE)).toBe(false);
|
|
221
223
|
expect(JSON.stringify(r.body.redactedPayload)).toContain(CANONICAL_MARKER);
|
|
222
224
|
});
|
|
@@ -259,13 +261,13 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: downstream-proj
|
|
|
259
261
|
// Hosts that don't advertise it soft-skip; hosts that DO advertise MUST serve a valid response.
|
|
260
262
|
const d = await readDiscovery();
|
|
261
263
|
const otelScrapeAdvertised = capabilityFamily<{ testSeams?: Record<string, unknown> }>(d, 'observability')?.testSeams?.otelScrape === true;
|
|
262
|
-
if (!otelScrapeAdvertised) return; // soft-skip — host honest about not implementing per RFC 0034 §A
|
|
264
|
+
if (!otelScrapeAdvertised) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!otelScrapeAdvertised` returned early (soft-skip — host honest about not implementing per RFC 0034 §A)'); // soft-skip — host honest about not implementing per RFC 0034 §A
|
|
263
265
|
|
|
264
266
|
const r = await acceptForRun(
|
|
265
267
|
`Reasoning trace mentioning ${CANARY_VALUE} verbatim.`,
|
|
266
268
|
'env-otel-redact-1',
|
|
267
269
|
);
|
|
268
|
-
if (r.status === 404) return; // envelope-accept seam itself not exposed — separate gate
|
|
270
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (envelope-accept seam itself not exposed — separate gate) (seam, prior step, or fixture unavailable)'); // envelope-accept seam itself not exposed — separate gate
|
|
269
271
|
expect(r.body.status).toBe('accepted');
|
|
270
272
|
|
|
271
273
|
const spansRes = await driver.get(
|
|
@@ -273,7 +275,7 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: downstream-proj
|
|
|
273
275
|
);
|
|
274
276
|
expect(
|
|
275
277
|
spansRes.status,
|
|
276
|
-
|
|
278
|
+
req('openwop.it.envelope-reasoning-secret-redaction.otel-span-attributes-for-the-envelope-emitting-node-must-not-include-plaintext-s',
|
|
277
279
|
'RFCS/0034-otel-collector-test-seam.md §B',
|
|
278
280
|
'host advertising capabilities.observability.testSeams.otelScrape MUST serve the seam (200) — 404 is non-conformant',
|
|
279
281
|
),
|
|
@@ -282,7 +284,7 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: downstream-proj
|
|
|
282
284
|
const serialized = JSON.stringify(spans);
|
|
283
285
|
expect(
|
|
284
286
|
serialized.includes(CANARY_VALUE),
|
|
285
|
-
|
|
287
|
+
req('openwop.it.envelope-reasoning-secret-redaction.otel-span-attributes-for-the-envelope-emitting-node-must-not-include-plaintext-s',
|
|
286
288
|
'SECURITY/invariants.yaml secret-leakage-otel-attribute',
|
|
287
289
|
'no canary plaintext from the envelope `reasoning` field may appear in any OTel span attribute',
|
|
288
290
|
),
|
|
@@ -293,19 +295,19 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: downstream-proj
|
|
|
293
295
|
// RFC 0034 §B: gate on capabilities.observability.testSeams.debugBundleExport.
|
|
294
296
|
const d = await readDiscovery();
|
|
295
297
|
const debugBundleAdvertised = capabilityFamily<{ testSeams?: Record<string, unknown> }>(d, 'observability')?.testSeams?.debugBundleExport === true;
|
|
296
|
-
if (!debugBundleAdvertised) return; // soft-skip — host honest about not implementing per RFC 0034 §A
|
|
298
|
+
if (!debugBundleAdvertised) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!debugBundleAdvertised` returned early (soft-skip — host honest about not implementing per RFC 0034 §A)'); // soft-skip — host honest about not implementing per RFC 0034 §A
|
|
297
299
|
|
|
298
300
|
const r = await acceptForRun(
|
|
299
301
|
`Step-by-step reasoning that surfaces ${CANARY_VALUE} from a prior tool result.`,
|
|
300
302
|
'env-bundle-redact-1',
|
|
301
303
|
);
|
|
302
|
-
if (r.status === 404) return; // envelope-accept seam itself not exposed — separate gate
|
|
304
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (envelope-accept seam itself not exposed — separate gate) (seam, prior step, or fixture unavailable)'); // envelope-accept seam itself not exposed — separate gate
|
|
303
305
|
expect(r.body.status).toBe('accepted');
|
|
304
306
|
|
|
305
307
|
const bundleRes = await driver.post('/v1/host/sample/test/debug-bundle/export', { runId: RUN_ID });
|
|
306
308
|
expect(
|
|
307
309
|
bundleRes.status,
|
|
308
|
-
|
|
310
|
+
req('openwop.it.envelope-reasoning-secret-redaction.debug-bundle-export-must-not-include-plaintext-secret-prefixed-substrings-from-e',
|
|
309
311
|
'RFCS/0034-otel-collector-test-seam.md §B',
|
|
310
312
|
'host advertising capabilities.observability.testSeams.debugBundleExport MUST serve the seam (200) — 404 is non-conformant',
|
|
311
313
|
),
|
|
@@ -313,7 +315,7 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: downstream-proj
|
|
|
313
315
|
const serialized = JSON.stringify(bundleRes.json);
|
|
314
316
|
expect(
|
|
315
317
|
serialized.includes(CANARY_VALUE),
|
|
316
|
-
|
|
318
|
+
req('openwop.it.envelope-reasoning-secret-redaction.debug-bundle-export-must-not-include-plaintext-secret-prefixed-substrings-from-e',
|
|
317
319
|
'SECURITY/invariants.yaml secret-leakage-debug-bundle-otel',
|
|
318
320
|
'no canary plaintext from envelope.reasoning may appear in the debug-bundle export',
|
|
319
321
|
),
|
|
@@ -330,12 +332,12 @@ describe.skipIf(HTTP_SKIP)('envelope-reasoning-secret-redaction: downstream-proj
|
|
|
330
332
|
`reasoning-variant-B with embedded ${CANARY_VALUE} canary — host MUST NOT route differently.`,
|
|
331
333
|
'env-route-B',
|
|
332
334
|
);
|
|
333
|
-
if (aResp.status === 404 || bResp.status === 404) return;
|
|
335
|
+
if (aResp.status === 404 || bResp.status === 404) return softSkip('blocked', 'precondition not met — `aResp.status === 404 || bResp.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
334
336
|
expect(aResp.body.status).toBe('accepted');
|
|
335
337
|
expect(bResp.body.status).toBe('accepted');
|
|
336
338
|
expect(
|
|
337
339
|
aResp.body.status,
|
|
338
|
-
|
|
340
|
+
req('openwop.it.envelope-reasoning-secret-redaction.envelope-acceptance-must-not-route-on-reasoning-contents-rfc-0030-a-normative-mu',
|
|
339
341
|
'RFCS/0030-envelope-reasoning-and-tier-one-subset.md §A',
|
|
340
342
|
'reasoning is informational only; routing decision MUST NOT depend on its contents',
|
|
341
343
|
),
|
|
@@ -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 } 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 HTTP_SKIP = !process.env.OPENWOP_BASE_URL;
|
|
38
40
|
|
|
@@ -78,15 +80,15 @@ describe('envelope-reasoning-shape: universal-kind schemas (RFC 0030 §A)', () =
|
|
|
78
80
|
const required = (schema.required as string[] | undefined) ?? [];
|
|
79
81
|
expect(
|
|
80
82
|
properties?.reasoning,
|
|
81
|
-
`RFC 0030 §A: ${kind}.schema.json MUST declare a \`reasoning\` property
|
|
83
|
+
req('openwop.it.envelope-reasoning-shape.schema-json-declares-optional-reasoning-string-per-rfc-0030-a', 'RFC 0030 §A', `RFC 0030 §A: ${kind}.schema.json MUST declare a \`reasoning\` property`),
|
|
82
84
|
).toBeDefined();
|
|
83
85
|
expect(
|
|
84
86
|
properties?.reasoning?.type,
|
|
85
|
-
'RFC 0030 §A: `reasoning` MUST be type: string on universal-kind schemas',
|
|
87
|
+
req('openwop.it.envelope-reasoning-shape.schema-json-declares-optional-reasoning-string-per-rfc-0030-a', 'RFC 0030 §A', 'RFC 0030 §A: `reasoning` MUST be type: string on universal-kind schemas'),
|
|
86
88
|
).toBe('string');
|
|
87
89
|
expect(
|
|
88
90
|
required.includes('reasoning'),
|
|
89
|
-
`RFC 0030 §A: ${kind}.schema.json MUST NOT list \`reasoning\` in required (OPTIONAL field; absence is a valid envelope shape)
|
|
91
|
+
req('openwop.it.envelope-reasoning-shape.schema-json-declares-optional-reasoning-string-per-rfc-0030-a', 'RFC 0030 §A', `RFC 0030 §A: ${kind}.schema.json MUST NOT list \`reasoning\` in required (OPTIONAL field; absence is a valid envelope shape)`),
|
|
90
92
|
).toBe(false);
|
|
91
93
|
});
|
|
92
94
|
}
|
|
@@ -96,7 +98,7 @@ describe('envelope-reasoning-shape: universal-kind schemas (RFC 0030 §A)', () =
|
|
|
96
98
|
const properties = schema.properties as Record<string, Record<string, unknown>> | undefined;
|
|
97
99
|
expect(
|
|
98
100
|
properties?.reasoning,
|
|
99
|
-
'RFC 0030 §A: `schema.response` is a side-channel ack envelope; it MUST NOT declare `reasoning`',
|
|
101
|
+
req('openwop.it.envelope-reasoning-shape.schema-response-schema-json-deliberately-omits-reasoning-side-channel-ack-per-rf', 'RFC 0030 §A', 'RFC 0030 §A: `schema.response` is a side-channel ack envelope; it MUST NOT declare `reasoning`'),
|
|
100
102
|
).toBeUndefined();
|
|
101
103
|
});
|
|
102
104
|
});
|
|
@@ -115,7 +117,7 @@ describe('envelope-reasoning-shape: backward-compat round-trip (RFC 0030 §A)',
|
|
|
115
117
|
const payload = { questions: [{ id: 'q1', question: 'What do you mean by X?' }] };
|
|
116
118
|
expect(
|
|
117
119
|
validateClarification(payload),
|
|
118
|
-
'RFC 0030 §A: existing v1.1 envelope without `reasoning` MUST remain valid',
|
|
120
|
+
req('openwop.it.envelope-reasoning-shape.clarification-request-validates-a-payload-without-reasoning-backward-compat', 'RFC 0030 §A', 'RFC 0030 §A: existing v1.1 envelope without `reasoning` MUST remain valid'),
|
|
119
121
|
).toBe(true);
|
|
120
122
|
});
|
|
121
123
|
|
|
@@ -126,13 +128,13 @@ describe('envelope-reasoning-shape: backward-compat round-trip (RFC 0030 §A)',
|
|
|
126
128
|
};
|
|
127
129
|
expect(
|
|
128
130
|
validateClarification(payload),
|
|
129
|
-
'RFC 0030 §A: envelope with optional `reasoning` populated MUST be accepted',
|
|
131
|
+
req('openwop.it.envelope-reasoning-shape.clarification-request-validates-a-payload-with-reasoning', 'RFC 0030 §A', 'RFC 0030 §A: envelope with optional `reasoning` populated MUST be accepted'),
|
|
130
132
|
).toBe(true);
|
|
131
133
|
});
|
|
132
134
|
|
|
133
135
|
it('error envelope validates without reasoning (backward compat)', () => {
|
|
134
136
|
const payload = { code: 'validation_failed', message: 'Could not match the schema.' };
|
|
135
|
-
expect(validateError(payload)).toBe(true);
|
|
137
|
+
expect(validateError(payload), req('openwop.it.envelope-reasoning-shape.error-envelope-validates-without-reasoning-backward-compat', 'RFC 0030 §A', 'error envelope validates without reasoning (backward compat)')).toBe(true);
|
|
136
138
|
});
|
|
137
139
|
|
|
138
140
|
it('error envelope validates with reasoning', () => {
|
|
@@ -141,11 +143,11 @@ describe('envelope-reasoning-shape: backward-compat round-trip (RFC 0030 §A)',
|
|
|
141
143
|
code: 'validation_failed',
|
|
142
144
|
message: 'Could not match the schema.',
|
|
143
145
|
};
|
|
144
|
-
expect(validateError(payload)).toBe(true);
|
|
146
|
+
expect(validateError(payload), req('openwop.it.envelope-reasoning-shape.error-envelope-validates-with-reasoning', 'RFC 0030 §A', 'error envelope validates with reasoning')).toBe(true);
|
|
145
147
|
});
|
|
146
148
|
|
|
147
149
|
it('schema.request validates without reasoning', () => {
|
|
148
|
-
expect(validateSchemaRequest({ envelopeType: 'vendor.acme.prd.create' })).toBe(true);
|
|
150
|
+
expect(validateSchemaRequest({ envelopeType: 'vendor.acme.prd.create' }), req('openwop.it.envelope-reasoning-shape.schema-request-validates-without-reasoning', 'RFC 0030 §A', 'schema.request validates without reasoning')).toBe(true);
|
|
149
151
|
});
|
|
150
152
|
|
|
151
153
|
it('rejects reasoning of non-string type (universal kinds use plain string, not string|null union)', () => {
|
|
@@ -155,7 +157,7 @@ describe('envelope-reasoning-shape: backward-compat round-trip (RFC 0030 §A)',
|
|
|
155
157
|
};
|
|
156
158
|
expect(
|
|
157
159
|
validateClarification(payload),
|
|
158
|
-
'RFC 0030 §A: universal-kind `reasoning` MUST be type: string; numbers reject',
|
|
160
|
+
req('openwop.it.envelope-reasoning-shape.rejects-reasoning-of-non-string-type-universal-kinds-use-plain-string-not-string', 'RFC 0030 §A', 'RFC 0030 §A: universal-kind `reasoning` MUST be type: string; numbers reject'),
|
|
159
161
|
).toBe(false);
|
|
160
162
|
});
|
|
161
163
|
});
|
|
@@ -163,29 +165,29 @@ describe('envelope-reasoning-shape: backward-compat round-trip (RFC 0030 §A)',
|
|
|
163
165
|
describe.skipIf(HTTP_SKIP)('envelope-reasoning-shape: capabilities.envelopes advertisement (RFC 0030 §C)', () => {
|
|
164
166
|
it('capabilities.envelopes.reasoning (when present) conforms to RFC 0030 §C', async () => {
|
|
165
167
|
const d = await readDiscovery();
|
|
166
|
-
if (d === null) return;
|
|
168
|
+
if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
|
|
167
169
|
const reasoning = capabilityFamily<{ reasoning?: Record<string, unknown>; tierOneSubsetCompliance?: unknown; reliability?: { completion?: Record<string, unknown> } & Record<string, unknown> }>(d, 'envelopes')?.reasoning;
|
|
168
|
-
if (reasoning === undefined) return; // optional block; host MAY omit
|
|
170
|
+
if (reasoning === undefined) return softSkip('blocked', 'precondition not met — `reasoning === undefined` returned early (optional block; host MAY omit) (seam, prior step, or fixture unavailable)'); // optional block; host MAY omit
|
|
169
171
|
expect(
|
|
170
172
|
typeof reasoning.supported,
|
|
171
|
-
'RFC 0030 §C: capabilities.envelopes.reasoning.supported MUST be boolean when block is advertised',
|
|
173
|
+
req('openwop.it.envelope-reasoning-shape.capabilities-envelopes-reasoning-when-present-conforms-to-rfc-0030-c', 'RFC 0030 §C', 'RFC 0030 §C: capabilities.envelopes.reasoning.supported MUST be boolean when block is advertised'),
|
|
172
174
|
).toBe('boolean');
|
|
173
175
|
if (reasoning.promptDirective !== undefined) {
|
|
174
176
|
expect(
|
|
175
177
|
['mandatory', 'advisory', 'off'],
|
|
176
|
-
'RFC 0030 §C: promptDirective MUST be one of the three documented values',
|
|
178
|
+
req('openwop.it.envelope-reasoning-shape.capabilities-envelopes-reasoning-when-present-conforms-to-rfc-0030-c', 'RFC 0030 §C', 'RFC 0030 §C: promptDirective MUST be one of the three documented values'),
|
|
177
179
|
).toContain(String(reasoning.promptDirective));
|
|
178
180
|
}
|
|
179
181
|
});
|
|
180
182
|
|
|
181
183
|
it('capabilities.envelopes.tierOneSubsetCompliance (when present) conforms to RFC 0030 §B', async () => {
|
|
182
184
|
const d = await readDiscovery();
|
|
183
|
-
if (d === null) return;
|
|
185
|
+
if (d === null) return softSkip('blocked', 'precondition not met — `d === null` returned early (seam, prior step, or fixture unavailable)');
|
|
184
186
|
const compliance = capabilityFamily<{ reasoning?: Record<string, unknown>; tierOneSubsetCompliance?: unknown; reliability?: { completion?: Record<string, unknown> } & Record<string, unknown> }>(d, 'envelopes')?.tierOneSubsetCompliance;
|
|
185
|
-
if (compliance === undefined) return; // optional; host MAY omit
|
|
187
|
+
if (compliance === undefined) return softSkip('blocked', 'precondition not met — `compliance === undefined` returned early (optional; host MAY omit) (seam, prior step, or fixture unavailable)'); // optional; host MAY omit
|
|
186
188
|
expect(
|
|
187
189
|
['strict', 'warn', 'off'],
|
|
188
|
-
'RFC 0030 §B: tierOneSubsetCompliance MUST be one of strict|warn|off',
|
|
190
|
+
req('openwop.it.envelope-reasoning-shape.capabilities-envelopes-tieronesubsetcompliance-when-present-conforms-to-rfc-0030', 'RFC 0030 §B', 'RFC 0030 §B: tierOneSubsetCompliance MUST be one of strict|warn|off'),
|
|
189
191
|
).toContain(String(compliance));
|
|
190
192
|
});
|
|
191
193
|
});
|
|
@@ -44,8 +44,8 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: seam emission (RFC 0032
|
|
|
44
44
|
byteOffset: 42,
|
|
45
45
|
},
|
|
46
46
|
});
|
|
47
|
-
if (r.status === 404) return;
|
|
48
|
-
expect(r.status).toBe(200);
|
|
47
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
48
|
+
expect(r.status, req('openwop.it.envelope-recovery-applied.accepts-a-well-formed-envelope-recovery-applied-payload-with-markdown-fence-path', 'RFC 0032 §B.6', 'accepts a well-formed `envelope.recovery.applied` payload with markdown-fence path')).toBe(200);
|
|
49
49
|
expect(r.body.event?.type).toBe('envelope.recovery.applied');
|
|
50
50
|
expect(r.body.event?.payload?.path).toBe('markdown-fence');
|
|
51
51
|
expect(r.body.event?.payload?.byteOffset).toBe(42);
|
|
@@ -58,8 +58,8 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: seam emission (RFC 0032
|
|
|
58
58
|
type: 'envelope.recovery.applied',
|
|
59
59
|
payload: { nodeId: 'writer', path },
|
|
60
60
|
});
|
|
61
|
-
if (r.status === 404) return;
|
|
62
|
-
expect(r.status, `path: ${path} MUST be accepted`).toBe(200);
|
|
61
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
62
|
+
expect(r.status, req('openwop.it.envelope-recovery-applied.accepts-each-spec-reserved-path-enum-value', 'RFC 0032 §B.6', `path: ${path} MUST be accepted`)).toBe(200);
|
|
63
63
|
expect(r.body.event?.payload?.path).toBe(path);
|
|
64
64
|
}
|
|
65
65
|
});
|
|
@@ -76,10 +76,10 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: SECURITY invariant envelo
|
|
|
76
76
|
recoveredContent: 'this is the pre-recovery output that should NOT be in the event', // forbidden per §G
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
|
-
if (r.status === 404) return;
|
|
79
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
80
80
|
expect(
|
|
81
81
|
r.status,
|
|
82
|
-
|
|
82
|
+
req('openwop.it.envelope-recovery-applied.rejects-payloads-carrying-a-recoveredcontent-field-pre-recovery-output-must-not',
|
|
83
83
|
'SECURITY/invariants.yaml §envelope-recovery-no-content-leak',
|
|
84
84
|
'envelope.recovery.applied payload MUST NOT carry pre-recovery output substrings; only the canonical {nodeId, path, byteOffset?} keys per RFC 0032 §B.6 + §G — the recovered content rides on downstream RunEventDoc, not on the recovery event',
|
|
85
85
|
),
|
|
@@ -97,10 +97,10 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: SECURITY invariant envelo
|
|
|
97
97
|
sourceSnippet: 'arbitrary extra key', // forbidden by additionalProperties: false in the schema
|
|
98
98
|
},
|
|
99
99
|
});
|
|
100
|
-
if (r.status === 404) return;
|
|
100
|
+
if (r.status === 404) return softSkip('blocked', 'precondition not met — `r.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
101
101
|
expect(
|
|
102
102
|
r.status,
|
|
103
|
-
|
|
103
|
+
req('openwop.it.envelope-recovery-applied.rejects-payloads-carrying-any-extra-field-outside-nodeid-path-byteoffset',
|
|
104
104
|
'schemas/run-event-payloads.schema.json §envelopeRecoveryApplied',
|
|
105
105
|
'envelope.recovery.applied has additionalProperties: false on the payload — any extra field MUST be rejected to prevent regression carriers for pre-recovery output (defense-in-depth on top of envelope-recovery-no-content-leak)',
|
|
106
106
|
),
|
|
@@ -122,6 +122,8 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: SECURITY invariant envelo
|
|
|
122
122
|
|
|
123
123
|
import { pollUntilTerminal } from '../lib/polling.js';
|
|
124
124
|
import { isFixtureAdvertised } from '../lib/fixtures.js';
|
|
125
|
+
import { req } from '../lib/requirement-ids.js';
|
|
126
|
+
import { softSkip } from '../lib/soft-skip.js';
|
|
125
127
|
|
|
126
128
|
const RECOVERY_FIXTURE = 'conformance-envelope-recovery-applied';
|
|
127
129
|
const RECOVERY_NODE_ID = 'structured-call';
|
|
@@ -150,29 +152,29 @@ async function runAndReadEvents(): Promise<ProgrammedRunEvent[] | null> {
|
|
|
150
152
|
|
|
151
153
|
describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: end-to-end through the envelope-validation pipeline', () => {
|
|
152
154
|
it('when mock LLM emits envelope wrapped in markdown fence, exactly one `envelope.recovery.applied` event fires with `path: "markdown-fence"`', async () => {
|
|
153
|
-
if (!isFixtureAdvertised(RECOVERY_FIXTURE)) return;
|
|
155
|
+
if (!isFixtureAdvertised(RECOVERY_FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(RECOVERY_FIXTURE)` returned early');
|
|
154
156
|
const seed = await programRecovery([
|
|
155
157
|
// Markdown-fenced JSON — dispatchStructured's strict parse fails,
|
|
156
158
|
// tryLenientParse() strips the fence + succeeds via the
|
|
157
159
|
// 'markdown-fence' path.
|
|
158
160
|
{ content: '```json\n{"result":"ok"}\n```' },
|
|
159
161
|
]);
|
|
160
|
-
if (seed.status === 404) return;
|
|
162
|
+
if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
161
163
|
expect(seed.status).toBe(200);
|
|
162
164
|
|
|
163
165
|
const events = await runAndReadEvents();
|
|
164
|
-
if (events === null) return;
|
|
166
|
+
if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
|
|
165
167
|
const recoveries = events.filter((e) => e.type === 'envelope.recovery.applied');
|
|
166
168
|
expect(
|
|
167
169
|
recoveries.length,
|
|
168
|
-
|
|
170
|
+
req('openwop.it.envelope-recovery-applied.when-mock-llm-emits-envelope-wrapped-in-markdown-fence-exactly-one-envelope-reco',
|
|
169
171
|
'RFCS/0032-envelope-reliability-events.md §B.6',
|
|
170
172
|
'exactly one envelope.recovery.applied event MUST fire when lenient parsing strips a markdown fence',
|
|
171
173
|
),
|
|
172
174
|
).toBe(1);
|
|
173
175
|
expect(
|
|
174
176
|
recoveries[0]?.payload?.path,
|
|
175
|
-
|
|
177
|
+
req('openwop.it.envelope-recovery-applied.when-mock-llm-emits-envelope-wrapped-in-markdown-fence-exactly-one-envelope-reco',
|
|
176
178
|
'RFCS/0032-envelope-reliability-events.md §B.6',
|
|
177
179
|
'path MUST identify the recovery strategy that engaged (markdown-fence here)',
|
|
178
180
|
),
|
|
@@ -180,18 +182,18 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: end-to-end through the en
|
|
|
180
182
|
});
|
|
181
183
|
|
|
182
184
|
it('recovery does NOT consume a retry attempt — `envelope.retry.attempted` does NOT fire as a consequence of recovery (RFC 0033 §D)', async () => {
|
|
183
|
-
if (!isFixtureAdvertised(RECOVERY_FIXTURE)) return;
|
|
185
|
+
if (!isFixtureAdvertised(RECOVERY_FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(RECOVERY_FIXTURE)` returned early');
|
|
184
186
|
const seed = await programRecovery([
|
|
185
187
|
{ content: '```json\n{"result":"ok"}\n```' },
|
|
186
188
|
]);
|
|
187
|
-
if (seed.status === 404) return;
|
|
189
|
+
if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
188
190
|
|
|
189
191
|
const events = await runAndReadEvents();
|
|
190
|
-
if (events === null) return;
|
|
192
|
+
if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
|
|
191
193
|
const retries = events.filter((e) => e.type === 'envelope.retry.attempted');
|
|
192
194
|
expect(
|
|
193
195
|
retries.length,
|
|
194
|
-
|
|
196
|
+
req('openwop.it.envelope-recovery-applied.recovery-does-not-consume-a-retry-attempt-envelope-retry-attempted-does-not-fire',
|
|
195
197
|
'RFCS/0033-envelope-completion-contract.md §D',
|
|
196
198
|
'recovery (parse fix-up) MUST NOT count against the retry budget — no envelope.retry.attempted may fire',
|
|
197
199
|
),
|
|
@@ -199,18 +201,18 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: end-to-end through the en
|
|
|
199
201
|
});
|
|
200
202
|
|
|
201
203
|
it('recovered envelope is subsequently accepted normally; downstream RunEventDoc carries the recovered content', async () => {
|
|
202
|
-
if (!isFixtureAdvertised(RECOVERY_FIXTURE)) return;
|
|
204
|
+
if (!isFixtureAdvertised(RECOVERY_FIXTURE)) return softSkip('inapplicable', 'capability or profile not advertised by this host — gate `!isFixtureAdvertised(RECOVERY_FIXTURE)` returned early');
|
|
203
205
|
const seed = await programRecovery([
|
|
204
206
|
{ content: '```json\n{"result":"recovered-ok"}\n```' },
|
|
205
207
|
]);
|
|
206
|
-
if (seed.status === 404) return;
|
|
208
|
+
if (seed.status === 404) return softSkip('blocked', 'precondition not met — `seed.status === 404` returned early (seam, prior step, or fixture unavailable)');
|
|
207
209
|
|
|
208
210
|
const events = await runAndReadEvents();
|
|
209
|
-
if (events === null) return;
|
|
211
|
+
if (events === null) return softSkip('blocked', 'precondition not met — `events === null` returned early (seam, prior step, or fixture unavailable)');
|
|
210
212
|
const nodeCompleted = events.find((e) => e.type === 'node.completed' && e.nodeId === RECOVERY_NODE_ID);
|
|
211
213
|
expect(
|
|
212
214
|
nodeCompleted,
|
|
213
|
-
|
|
215
|
+
req('openwop.it.envelope-recovery-applied.recovered-envelope-is-subsequently-accepted-normally-downstream-runeventdoc-carr',
|
|
214
216
|
'RFCS/0032-envelope-reliability-events.md §B.6',
|
|
215
217
|
'recovered envelope MUST reach node.completed — recovery does not block downstream acceptance',
|
|
216
218
|
),
|
|
@@ -221,7 +223,7 @@ describe.skipIf(HTTP_SKIP)('envelope-recovery-applied: end-to-end through the en
|
|
|
221
223
|
const completedPayload = JSON.stringify(nodeCompleted?.payload ?? {});
|
|
222
224
|
expect(
|
|
223
225
|
completedPayload.includes('recovered-ok'),
|
|
224
|
-
|
|
226
|
+
req('openwop.it.envelope-recovery-applied.recovered-envelope-is-subsequently-accepted-normally-downstream-runeventdoc-carr',
|
|
225
227
|
'RFCS/0032-envelope-reliability-events.md §B.6',
|
|
226
228
|
'recovered structured data MUST flow to the downstream RunEventDoc unchanged',
|
|
227
229
|
),
|