npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@openwop/openwop-conformance

v1.46.0

Published

Production-ready black-box conformance suite for OpenWOP v1.0 compliant servers.

Downloads

4,817

Readme

@openwop/openwop-conformance — Conformance Suite for the Multi-Agent Workflow Orchestration Protocol

openwop is an open, wire-level protocol for multi-agent workflow orchestration — a single contract for runs in which LLM agents, deterministic tools, sub-workflows, and human reviewers collaborate, with durable suspend / resume, replay, version negotiation, and observability owned by the protocol itself. This package is the black-box conformance suite: point it at any OpenWOP-compliant server (your own or a third party's) and it issues real HTTP requests against the spec'd endpoints and asserts that responses match.

npm install @openwop/openwop-conformance
# or run without install:
npx @openwop/openwop-conformance --base-url https://api.example.com --api-key hk_test_...

Spec: github.com/openwop/openwop · See CHANGELOG.md below for release history.

The suite is intentionally self-contained — it does NOT depend on the reference implementation. A spec-compliant server written in any language can run this suite against itself by spinning up its server, exporting the env vars, and running npx vitest run.

Status: Tracks the FINAL v1 protocol contract. The suite version evolves independently as new scenarios ship (vendor-neutral redaction, cost attribution, post-v1 ecosystem triggers); see CHANGELOG.md for the current release.


Quickstart

Two ways to run: the friendly openwop-conformance CLI (recommended for operators) or vitest directly (recommended for CI).

CLI

cd conformance
npm install

# Build the CLI binary
npm run build:cli

# Server-free subset (no deployment target needed)
./dist/cli.js --offline

# Full suite against a deployed server
./dist/cli.js \
  --base-url https://api.example.com \
  --api-key hk_test_abc123 \
  --impl acme-openwop-server --impl-version 1.0

# Filter by test-name pattern
./dist/cli.js --base-url ... --api-key ... --filter "discovery|errors"

./dist/cli.js --help for the full flag reference. Env vars (OPENWOP_BASE_URL, OPENWOP_API_KEY, OPENWOP_IMPLEMENTATION_*) override CLI flags only when the flag is unset.

Direct vitest

cd conformance
npm install

export OPENWOP_BASE_URL="https://api.example.com"
export OPENWOP_API_KEY="hk_test_..."

npx vitest run                                 # full suite (parallel files, ~95s)
npx vitest run src/scenarios/discovery.test.ts # single file
npm run test:strict                            # full suite, no-file-parallelism

test:strict vs test. The default test script runs files in parallel (vitest default, ~3-5× faster). Most scenarios are isolation-safe at that level. Two exceptions document --no-file-parallelism as their canonical execution mode:

  • production-backpressure.test.ts — saturates the host's inflightCap; under parallel execution, neighbor tests posting /v1/runs during the saturation window see a 503 from the cap (cap-collateral). The scenario soft-skips its envelope assertions when this happens (logs a warning); test:strict exercises the full envelope contract.
  • OTel scenarios (otel-emission.test.ts, otel-trace-propagation.test.ts, metric-emission.test.ts) — each vitest worker spawns its own collector and only one can bind the configured OTLP port; concurrent file execution causes ephemeral-port fallbacks that don't receive the host's traffic.

Run npm run test for normal CI cadence; npm run test:strict when claiming full envelope coverage for production-profile + OTel claims.

Optional environment flags

| Variable | Effect | | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | OPENWOP_REQUIRE_BEHAVIOR=true | Capability-gated scenarios (audit-log integrity, rate-limit envelope, multi-region idempotency, configurableSchema, webhook sig versioning, etc.) FAIL instead of skipping when the host doesn't advertise the profile. Lets a host claim "full coverage" mechanically. See coverage.md §"Capability-gated scenarios". | | OPENWOP_TEST_PUBLIC_REGISTRY=true | Runs registry-public.test.ts against the hosted registry at packs.openwop.dev. Skipped by default so the suite doesn't depend on outbound connectivity. | | OPENWOP_OTEL_COLLECTOR=true | Boots the in-suite OTLP collector for otel-emission.test.ts, otel-trace-propagation.test.ts, metric-emission.test.ts, and otel-emission-grpc.test.ts. The collector accepts OTLP/HTTP-JSON (application/json), OTLP/HTTP-protobuf (application/x-protobuf — hand-rolled decoder at src/lib/otlp-protobuf.ts), and OTLP/gRPC (when OPENWOP_OTEL_COLLECTOR_GRPC=true — h2c HTTP/2 + hand-rolled framing at src/lib/grpc-framing.ts). Zero new npm deps. Hosts may emit via OTEL_EXPORTER_OTLP_PROTOCOL=http/json, http/protobuf, or grpc. Skipped by default. Run OTel scenarios with --no-file-parallelism — each vitest worker spawns its own collector and only one can bind the same port, so concurrent file execution causes ephemeral-port fallbacks that don't receive the host's OTLP traffic. | | OPENWOP_OTEL_COLLECTOR_GRPC=true | Boots the parallel OTLP/gRPC collector alongside the HTTP one (h2c HTTP/2 on a separate port). Shares the same spans() + metrics() store; spans captured over either transport surface in getCollector().spans(). Requires OPENWOP_OTEL_COLLECTOR=true. Same --no-file-parallelism requirement applies. | | OPENWOP_OTEL_COLLECTOR_GRPC_PORT=4317 | Bind the OTLP/gRPC collector on a specific port (default 4317, OTLP/gRPC convention). The host MUST be configured with OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:<port> AND OTEL_EXPORTER_OTLP_PROTOCOL=grpc. | | OPENWOP_OTEL_COLLECTOR_PORT=14318 | Bind the OTel collector on a specific port (default 4318). The host MUST be configured with OTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:<port>. | | OPENWOP_WEBHOOK_ALLOW_PRIVATE=true | Hosts implementing the webhook SSRF guard (rejecting loopback / RFC1918 / link-local destinations) MUST advertise this flag for the loopback test receiver in webhook-signed-delivery.test.ts to be accepted. The SQLite reference host honors this env var; the scenario soft-skips when the host rejects the URL. | | OPENWOP_MCP_FAKE_SERVER=true | Boots the synthetic MCP peer for mcp-tool-roundtrip.test.ts. | | OPENWOP_MCP_REAL_SERVER_URL=<base-url> | Points the MCP wire-shape probe at a real MCP server. The probe POSTs JSON-RPC and reads a single-JSON response — matches MCP's streamable-http transport in single-response mode. Does NOT support stdio transport (which is what most modelcontextprotocol/servers references default to) or SSE-streamed responses; an operator collecting interop evidence today runs a custom StreamableHTTPServerTransport-style server that returns a single JSON body per request. Adding SSE-frame parsing is tracked in docs/PROTOCOL-GAP-CLOSURE-PLAN.md Track 6. Assertions relax to shape-only. When both this and OPENWOP_MCP_FAKE_SERVER are set, the real URL wins. Phase 3 T3.4 interop-evidence path. | | OPENWOP_A2A_FAKE_PEER=true | Boots the synthetic A2A peer for a2a-task-roundtrip.test.ts. | | OPENWOP_A2A_REAL_PEER_URL=<base-url> | Points the A2A AgentCard + task-lifecycle probe at a real reference A2A peer. Drift-point subtests (AUTH_REQUIRED / REJECTED) stay fake-peer-only — real peers don't expose a state-forcing API. Phase 3 T3.4 interop-evidence path. | | OPENWOP_FORCE_RATE_LIMIT=true | Signals the host (test-only key) to fabricate a 429 so rate-limit-envelope.test.ts can exercise envelope shape deterministically. | | OPENWOP_TEST_PROMPT_PACK_INSTALLED=true | Promotes the prompt-pack-install.test.ts existence claim from soft-skip to hard assertion (RFC 0028 §B). Set when the target host is known to have at least one prompt pack installed at boot — RFC 0028 §B does NOT require any host with endpointsSupported: true to have packs installed, so the suite stays conformant against a fresh production host with no pack subscriptions when the flag is unset. The in-tree workflow-engine sample auto-installs vendor.openwop.prompt-sample via promptPackLoader.ts, so operators running against it should set the flag. |

Exit code is non-zero on any failed assertion.


What's Covered

The current suite has 380 scenario files under src/scenarios/. 2026-06-29 (RFC 0120 — connection-pack apiHosts credential-egress allow-list, suite 1.45.0 → 1.46.0) added connection-pack-apihosts.test.ts (always-on schema legs: the connection-pack-apihosts-valid fixture validates, an openapi-reach provider omitting apiHosts is rejected by the conditional-MUST allOf, and IP/wildcard/port/single-label/uppercase entries are each rejected; always-on matching-rule legs: the item-10 dot-anchored eTLD+1 suffix-containment rule permits subdomains + a tighter exact host and fails closed with no substring/suffix/prefix escape — the public tests for the protocol-tier connection-pack-api-host-shape + connection-pack-egress-host-bound invariants; plus a capability-gated behavioral egress allow-list leg over the new POST /v1/host/sample/connection-packs/egress-check seam, soft-skipping when unadvertised/unwired). 2026-06-28 (RFC 0118 — parallel sub-workflow fan-out and join, suite 1.44.0 → 1.45.0) added dispatch-fanout-parallel.test.ts (always-on schema legs for dispatch-config.schema.json — accepts a valid parallel config + each joinPolicy.mode + maxConcurrency, rejects unknown enum values / additionalProperties on joinPolicy / non-positive maxConcurrency, keeps a pre-RFC-0118 config valid — and the dispatchFanOut/dispatchJoin event $defs of run-event-payloads.schema.jsonfanOutPolicy const parallel, childCount ≥ 2, the required replay-deterministic mergeOrder; capability-gated behavioral legs over POST /v1/host/sample/dispatch/fanout (wait-all/collect → joinOutcome: satisfied + full children[] + mergeOrder) plus the un-gated registration-rejection leg (fanOutSupported:false host MUST reject parallel with a 4xx); soft-skips on absent dispatch.fanOutSupported / parallelfanOutPolicies). 2026-06-27 (RFC 0117 — front-end plugin packs, suite 1.43.0 → 1.44.0) added frontend-plugin-packs.test.ts (always-on schema legs for frontend-plugin-manifest.schema.json + the ui-plugin/1 envelope ui-plugin-message.schema.json: manifest validity, runtime-forbidden, path-traversal-guarded entry, the closed hostApi allowlist, the version-token artifact_conflict + currentVersion concurrency shape, and no credential-bearing envelope field (additionalProperties:false); the capability-shape leg asserts isolation pins to the cross-origin-iframe const; capability-gated behavioral legs over POST /v1/host/sample/ui-plugin/rpc assert an undeclared method → method_not_allowed and a stale artifact.writeartifact_conflict with no persist; soft-skips on absent capabilities.uiPlugins.supported or 404/403 on the seam (RFC 0117 stays Active pending host witnesses); the public test for the protocol-tier frontend-plugin-{isolation,egress,rpc-allowlist,no-byok} invariants). 2026-06-26 (RFC 0116 — portable prompt-prefix cache, suite 1.42.0 → 1.43.0) added prompt-prefix-cache.test.ts (advertisement-shape on aiProviders.promptPrefixCache + behavioral legs over the OPTIONAL POST /v1/host/sample/ai/generate seam (host-sample-test-seams.md §16): (a) outcome-invariance — a generate with cachePrefixId and a control without produce the same accepted envelope + identical provider.usage.inputTokens/outputTokens (cost-hint-only, replay-invariant); (b) cache-hit observable — a repeat generate shows cacheReadTokens > 0; (c) cross-tenant isolation — tenant B’s first use of tenant A’s cachePrefixId shows cacheReadTokens == 0, the public test for the protocol-tier prompt-prefix-cache-cross-tenant-isolation invariant (the host MUST key its provider cache by (tenant, cachePrefixId), never global); (d) secret-free — the cost-only cache-token fields carry no prompt substrings (SR-1); soft-skips on absent aiProviders.promptPrefixCache.supported or 404/405 on the seam, since RFC 0116 defers reference-host impl as provider-gated). 2026-06-26 (RFC 0114 — A2UI surface deltas, suite 1.41.0 → 1.42.0) added a2ui-surface-delta-transport.test.ts (always-on legs use a cast-free, dependency-free client-side RFC 6902 applier + Ajv2020 to assert: the new a2ui-surface-delta-frame.schema.json compiles, the op enum excludes test, a full surface + delta frames reconstruct the expected tree AND equal the full a non-negotiating subscriber materializes and re-validate against the closed catalog, an out-of-catalog/script-bearing delta fails closed-catalog validation post-patch — the a2ui-surface-no-code-exec boundary holds — and the recorded envelope is always the full surface; the HTTP leg is capability-gated on a2uiSurface.deltaTransport and soft-skips on absent host/capability or 404/405 on the OPTIONAL GET /v1/host/sample/a2ui/surface/materialized seam). 2026-06-26 (RFC 0111 — context economy, suite 1.40.0 → 1.41.0) added context-budget-transcript-bound.test.ts (capability-gated on multiAgent.executionModel.contextBudget.transcriptTokenBudget being present via behaviorGate(openwop-context-budget, …) — drives the conformance-context-budget-multiturn orchestrator fixture, reads the host’s per-iteration accounting via the OPTIONAL seam GET /v1/host/sample/agent/transcript-window?runId=…&iteration=N (host-sample-test-seams.md §14), and asserts tokenCount ≤ transcriptTokenBudget in the advertised tokenCounter unit, that every eventId in the seam accounting is a real persisted run event (internal-consistency cross-check against /v1/host/sample/test/runs/:runId/events), recent-tail + no-double-count, every summarizedRanges.summaryRef has a matching context.summarized event, and keepLastTurns recent turns are fed verbatim — never inside a summarized range; soft-skips on 404/405 since the RFC defers reference-host impl) + context-summarization-replay.test.ts (capability-gated on multiAgent.executionModel.contextBudget.summarization.supported via behaviorGate(openwop-context-summarization, …) — replays the run via :fork mode:replay and asserts the recorded context.summarizedsummaryRef records are REUSED, never re-summarized, the direct analogue of RFC 0041 envelope-refusal recovery; soft-skips when the event-log seam is unwired, no replay mode is advertised, or the run produced no summarization). 2026-06-26 (RFC 0113 — memory injection budget, suite 1.39.0 → 1.40.0) added memory-injection-budget.test.ts (capability-gated on memory.injectionBudget.supported === true via behaviorGate(openwop-memory-injection-budget, …) — drives the conformance-agent-memory-injection-budget fixture through the host-sample memory seam and asserts the budgeted injection read's cumulative tokens ≤ the requested tokenBudget in the advertised tokenCounter unit (o200k_base/cl100k_base/chars/host-defined), an over-budget single entry is omitted not truncated, and re-asserts SR-1 ([REDACTED:<secretId>] content) + CTI-1 (cross-tenant probe returns empty) on the budgeted path; the rank:'relevance' leg DELEGATES to memory.search semantic (RFC 0080) and asserts relevance ordering differs from recency ONLY when the host ALSO advertises memory.search semantic, else it soft-skips — there is NO ranking primitive in injectionBudget; soft-skips on hosts that do not advertise memory.injectionBudget). 2026-06-26 (RFC 0112 — compact tool projection, suite 1.38.0 → 1.39.0) added tool-catalog-compact-projection.test.ts (capability-gated on toolCatalog.compactView === true via behaviorGate(openwop-tool-catalog-compact, …) — drives GET /v1/tools?view=compact and asserts the host returns the { tools: CompactToolDescriptor[] } envelope where every descriptor validates against compact-tool-descriptor.schema.json with the heavy ToolDescriptor fields dropped, every present inputSchema satisfies the self-contained compact structural subset (top-level type:"object"+properties; no $ref/oneOf/allOf/anyOf/not/patternProperties/dependentSchemas), and the compact tools[] toolId set EQUALS the standard view set for the same principal (projection completeness); soft-skips on hosts that do not advertise toolCatalog.compactView). 2026-06-26 (RFC 0115 — run transport economy, suite 1.37.0 → 1.38.0) added run-transport-economy.test.ts (capability-gated on restTransport.conditionalRunGet === true and a non-empty restTransport.contentEncodings — drives GET /v1/runs/{runId} and asserts a sequence-derived strong ETag on the 200, If-None-Match304 with an empty body while the run is unchanged, the ETag ROTATES after the conformance-approval fixture advances waiting-approval → completed (proving it derives from the latest persisted event-log sequence, not a coarser signal that would leave a 304 stale), and each advertised Content-Encoding (gzip baseline; br/zstd optional) round-trips byte-identically to the identity body; soft-skips on hosts that do not advertise restTransport). 2026-06-24 (RFC 0110 — channel presence, behavioral leg) added channel-presence-behavioral.test.ts (capability-gated on channelPresence.supported via behaviorGate('openwop-channel-presence', …) — drives the POST /v1/host/sample/channel-presence/snapshot seam and asserts a live channel.presence snapshot is the CLOSED {conversationId,present,typing} shape (no PII), every ref is an opaque RFC 0041 user:/agent: subject, typing ⊆ present, and the snapshotting member is non-vacuously present; soft-skips on 404/405 — a host whose presence is bound to a product flow witnesses via its own route test + an INTEROP-MATRIX row, the RFC 0086 dual-staging). 2026-06-24 (RFC 0110 — channel presence, Accept cycle) added channel-presence-shape.test.ts (always-on server-free — the OPTIONAL channel.presence ephemeral payload validates a conforming snapshot, REQUIRES conversationId+present, is CLOSED additionalProperties:false (the no-PII guard), typing optional; channel.presence is in the RunEventType enum; the channelPresence capability block is declared + closed). 2026-06-24 (RFC 0109 — conversation-turn model provenance, Accept cycle) added conversation-turn-model-provenance-shape.test.ts (always-on server-free — agent.model {provider, model} validates conforming / both-required / closed-SR-1 / optional-back-compat, + the conversationTurnModelProvenance capability declared + closed). 2026-06-24 (RFC 0108 — self-hosted / OpenAI-compatible provider class, Accept cycle, suite 1.36.0 → 1.37.0) added the gated behavioral honesty leg aiproviders-selfhosted-honesty.test.ts (gated on aiProviders.selfHosted.length > 0 via behaviorGate('openwop-selfhosted-providers', …) — drives POST /v1/host/sample/ai/call against an advertised selfHosted id and asserts §A.2 the dispatch reaches a real configured endpoint (success or transport error — never capability_not_provided / provider_not_supported, which would prove a dishonest advertisement with no endpoint behind it) and §D the endpoint location — supplied out-of-band via OPENWOP_TEST_COMPAT_ENDPOINT, checked as the raw string + bare host/host:port — never appears in the seam response or error payload; soft-skips on 404 / when the env var is unset for the §D leg). 2026-06-24 (RFC 0108, suite 1.35.0 → 1.36.0) added the always-on server-free shape leg aiproviders-selfhosted-shape.test.ts (the additive aiProviders.selfHosted advertisement: a string[] with uniqueItems/minLength:1 items, absent from aiProviders.required, validates a conforming array via Ajv2020 while rejecting non-array / duplicate / empty-string forms, and enforces the two §A rules JSON Schema cannot express — §A.1 every selfHosted entry is a subset of supported, and §A.3 / self-hosted-endpoint-no-disclosure no entry is URL-shaped (://, bare host:port, or leading / path) — exercised against good/bad example docs). 2026-06-23 (RFC 0106 — real-time voice session profile, Accept cycle) added six gated behavioral scenarios driving the openwop-app live host (rev 00293-89w): voice-transcription-streaming + voice-transcription-unadvertised (the call-transcriber seam; the latter gated-by-absence), voice-synthesis-streaming (the stream:true synthesis arm → metadata-only voice.synthesis_chunk events), voice-bargein-no-partial-leak (the /voice/barge-in seam — voice.barge_invoice.cancelled with no chunk after; graduated voice-bargein-no-partial-leak reference-impl→protocol on the live proof), and voice-interim-not-durable + voice-streamref-tenant-bound (§F INV-1/INV-4; soft-skip on the §E transcription_unsupported / no-live-streamRef path — stay reference-impl until a host with a scripted-interim / live-streamRef arm proves them). 2026-06-23 (RFC 0107 — publishable declarative pack kinds) added one: registry-declarative-kinds.test.ts (always-on server-free — the registry version-manifest carries the kind discriminator + per-kind declarative payload, runtime is conditional on kind via allOf if/then/else, published artifact-type and connection manifests validate, and a declarative-with-runtime or node-without-runtime manifest is rejected). 2026-06-23 (RFC 0107 correction, suite 1.34.0 → 1.35.0) extended that scenario with two cases — a published chat-card pack manifest (kind: "card", RFC 0071) validates, and the never-canonical kind: "chat-card" is rejected — fixing a kind-string mismatch where RFC 0107's published schema enumerated chat-card while RFC 0071 (authoritative) defines card (no scenario-file count change; cases added to the existing file). 2026-06-23 (RFC 0106 — real-time voice session profile, Phase 2) added one: voice-event-payloads-shape.test.ts (always-on server-free — all seven voice.* types are in the RunEventType enum, each has a payload $def via typeIndex, voice.transcript REQUIRES contentTrust:"untrusted" (the schema-enforced half of voice-transcript-untrusted), voice.synthesis_chunk is metadata-shaped (seq+mimeType required; bytes by url/streamRef), and the content-free events reject unknown properties). Phase 2 also lands the voice.* payload $defs in run-event-payloads.schema.json + the asyncapi.yaml messages + the four §F SECURITY/invariants.yaml rows (1 protocol-tier voice-transcript-untrusted + 3 reference-impl behavioral, graduating at Active → Accepted). The gated behavioral legs (voice-transcription-streaming/-unadvertised, voice-synthesis-streaming + the three behavioral invariant scenarios) land with the reference host at Active → Accepted. 2026-06-23 (RFC 0106 — real-time voice session profile, Phase 1) added one: aiproviders-realtimevoice-shape.test.ts (always-on server-free — the aiProviders.realtimeVoice object advertisement: the four sub-flags transcription/synthesis/turnDetection/bargeIn are declared, realtimeVoice is absent from aiProviders.required, the turnDetection/bargeIn ⇒ transcription dependentRequired closure and the synthesis ⇒ speechSynthesis if/then closure hold via Ajv2020, and out-of-enum / boolean sub-flag values are rejected). The gated behavioral legs (voice-transcription-streaming / -unadvertised, voice-synthesis-streaming) and the four §F live-ingress invariant scenarios land in Phase 2 at the Active → Accepted cycle. 2026-06-22 (RFC 0101 — multi-party group conversation) added two — multi-party-conversation-shape.test.ts (always-on server-free — asserts the three additive RFC 0101 wire facts: a 3-agent council conversation.opened participant roster (instance ids) + a user opening turn validates, every role: 'agent' turn carrying a roster-instance speakerId validates while one OMITTING speakerId MUST FAIL schema validation (the allOf/if role==='agent' then required:['speakerId'] conditional), a non-AgentRef participant item is rejected, the capabilities.multiPartyConversation { supported, maxParticipants? } block is declared + closed and rejects extras / maxParticipants:1 / a missing supported, and the non-participant membership predicate is asserted server-free) and multi-party-conversation-behavioral.test.ts (capability-gated on multiPartyConversation.supported via behaviorGate('openwop-multi-party-conversation', …) — drives the conformance-only seam POST /v1/host/sample/conversation/multi-party/{open,exchange} (host-sample-test-seams.md, since RFC 0101 mints no normative client trigger to open a council): a 3-agent council opens and a roster-valid attributed agent turn is accepted, while a role:'agent' turn missing speakerId, a non-participant speakerId, and an over-maxParticipants open are each rejected with error.code:'validation_error' (status-tolerant 400/422 per RFC 0005 §E); soft-skips on 404/405 — reference impl: the postgres example host). 2026-06-20 (RFC 0105 — speech synthesis adapter) added three: aiproviders-speechsynth-shape.test.ts (always-on server-free — the aiProviders.speechSynthesis const "supported" flag is declared, absent from aiProviders.required, and a string-const advertisement validates while the object form {supported:true} is rejected), speech-synthesis-roundtrip.test.ts (gated on aiProviders.speechSynthesis === "supported" via behaviorGate('openwop-speech-synthesis', …) — an advertising host's callSpeechSynthesizer round-trip via the POST /v1/host/sample/ai/call-speech-synthesizer seam returns audio with EXACTLY ONE of url/base64, a non-empty mimeType, and the echoed voiceId; soft-skips on 404), and speech-synthesis-unadvertised.test.ts (gated-by-absence via behaviorGate('openwop-speech-synthesis-unadvertised', …) — a host NOT advertising speechSynthesis MUST reject the call with speech_synthesis_unsupported, never a silent no-op). 2026-06-19 (RFC 0104 — portable HITL approver routing) added one: interrupt-approver-routing.test.ts (server-free Ajv2020 — the interrupt.approverRouting capability block shape, the additive optionality of approverGroupRefs / approverRoleRefs / audience on the ApprovalData schema, the closed audience object, and the §"Portable approver routing" notifyTargets reference rule that audience DEFAULTS to the resolved eligibility union when omitted and OVERRIDES it when present; the capability-gated leg asserts an advertising host's interrupt.approverRouting is honest — refKinds ⊆ {group, role}, audience boolean — and soft-skips when the host does not advertise the capability). 2026-06-17 (RFC 0103 — localized content surface) added one: localized-content-delivery.test.ts (server-free Ajv2020 — the four content schemas + the §C resolveSection merge + §A capability coherence; the public test for content-published-cache-no-draft / content-response-tenant-scoped / content-no-cross-tenant-enumeration; the live legs gate on capabilities.content.supported and soft-skip without a GET /v1/content/pages/{slug} target). 2026-06-15 (RFC 0102 — A2UI agent-authored interface surfaces) added five: a2ui-surface-shape.test.ts (server-free Ajv2020 — the closed core ui.a2ui-surface payload validates, while an out-of-catalog component / extra script-bearing property / unenumerated catalogVersion / action.target outside enum["resume","exchange"] each fail; the structural half of a2ui-action-confinement and the enabling precondition for the render-side a2ui-surface-no-code-exec / a2ui-surface-no-network-egress reference-app probes), a2ui-surface-degrades.test.ts (the kind is optional/advertised, not a MUST-recognize universal kind, and an unadvertised kind is gated — N6 — never crashing the run), a2ui-surface-version-refusal.test.ts (the enumerated catalogVersion rejects an unadvertised version → unknown_schema_version, and the surface schema carries no external $ref), a2ui-surface-replay.test.ts (all $refs internal so a stored surface :fork/replays deterministically; same-correlationId + divergent typeenvelope_correlation_conflict), and a2ui-untrusted-blocks-approval.test.ts (a meta.contentTrust:'untrusted' surface is trust-gated and MUST NOT advance an approval interrupt — composition of untrusted_content_blocks_approval). The four behavioral legs soft-skip on 404 (host-pending; the openwop-app reference renderer is the render-side probe). 2026-06-14 (RFCs 0099/0100 — external-event trigger ingestion + async/durable A2A tasks) added one new scenario (trigger-ingestion.test.ts) and extended a2a-task-roundtrip.test.ts with the RFC 0100 async subtests: trigger-ingestion.test.ts (RFC 0099 — always-on TriggerEvent / TriggerSubscriptionRegistration schema legs incl. the §F.1 per-source one-of, the AttachmentRef.ref-only rule + raw-URL rejection backing trigger-ingestion-ssrf, and the content-free trigger.delivery.attempted shape backing trigger-ingestion-content-redaction; plus a capability-gated behavioral leg on triggerBridge.ingestion driving the POST /v1/host/sample/trigger-bridge/ingest seam for SSRF refusal + header-redaction), and the a2a-task-roundtrip.test.ts additions (RFC 0100 — always-on A2ATaskState + capabilities.a2a shape legs incl. the lowercase-hyphen state enum, the PushConfig url-required + truncated-tokenFingerprint rule backing a2a-push-egress-ssrf, the no-inline-inputs additionalProperties:false SR-1 check; plus capability-gated durable-tasks/get-after-disconnect and push-SSRF behavioral legs on a2a.durableTasks / a2a.pushNotifications via the /v1/host/sample/a2a/tasks/* seam). 2026-06-13 (RFCs 0096/0097/0098 — reviewable learning, standing goals, agent-platform portability) added three always-on-plus-gated scenarios: proposal-reviewable-learning.test.ts (RFC 0096 — the agents.proposals shape + the Proposal round-trip incl. the dropped rule kind + the content-free proposal.{created,activated} events, plus a gated apply-without-scope→403 leg; backs proposal-inert-until-applied + proposal-no-resynthesis), goal-standing-continuation.test.ts (RFC 0097 — the agents.goals shape + the Goal round-trip + the content-free goal.{evaluated,closed} events, plus gated bounded-termination→422 + judge-only-completion legs; backs goal-continuation-bounded + goal-completion-judge-only), and export-bundle-portability.test.ts (RFC 0098 — the portability shape incl. the import⇒dryRun if/then + the ExportBundle round-trip rejecting every credential-named field + the content-free import.applied event, plus a gated literal-credential-import→422 leg; backs export-bundle-no-credential-material). 2026-06-11 (RFCs 0093/0094 — protocol hardening + wire-shape reconciliation) added five: version-fold.test.ts (the version-negotiation.md §X-Force-Engine-Version cross-version matrix through the previously-orphaned conformance-version-fold fixture — closes catalog gap F5; soft-skips when Capabilities.testing.forceEngineVersionRange is unadvertised), stream-text-fixture.test.ts (the stream-modes.md §messages fold through the deterministic stream-text mock provider + the previously-orphaned conformance-stream-text fixture — closes catalog gap F1), i18n-negotiation.test.ts (gated on capabilities.i18n via behaviorGate('openwop-i18n', …) — an unsupported or malformed Accept-Language never 400s, Content-Language reflects the locale actually used, and error code strings stay the canonical English tokens), grpc-transport.test.ts (gated on capabilities.grpc via behaviorGate('openwop-grpc-transport', …) — advertisement-shape only per grpc-transport.md §Field semantics: service MUST be openwop.v1.Engine, the tls enum, grpcs?:// endpoint URIs, supportedTransports includes grpc when exposed, production claimants require tls: "required"; no gRPC dialing), and webhook-tenant-isolation.test.ts (RFC 0093 §A.3 — backs the new protocol-tier webhook-cross-tenant-isolation invariant; a two-tenant proof through the /v1/host/sample/test/surface seam plus black-box registration-surface scoping). spec-corpus-validity.test.ts also gained the RFC 0094 §A satisfiability probe: canonical createRun bodies MUST pass the composed request schema (closed via unevaluatedProperties: false at the composition site, never inside an allOf branch) and an undeclared property MUST fail. 2026-06-07 (RFCs 0090/0091/0092 — verifier turn + convergence, multimodal perception input, agent capability requirements) added six: the always-on, server-free shape probes agent-verifier-shape.test.ts, aiproviders-input-shape.test.ts, agent-requires-capabilities-shape.test.ts, plus the capability-gated behavioral legs agent-capability-degraded-projection.test.ts (RFC 0092 §B — the degraded[] projection on GET /v1/agents, black-box, non-vacuous via OPENWOP_DEGRADED_CAPABILITY_AGENT_ID), callai-multimodal.test.ts (RFC 0091 §A/§B — advertised modality accepted / unadvertised → unsupported_modality, via the POST /v1/host/sample/ai/call seam), and verifier-gating.test.ts (RFC 0090 §B — a fail verdict blocks commit, via the POST /v1/host/sample/agents/verify-run seam). The three behavioral legs soft-skip by default and hard-fail under OPENWOP_REQUIRE_BEHAVIOR=true — the Active→Accepted reference-host proof for each RFC. 2026-06-02 (RFC 0082 §B — deployment channel resolve-and-pin, production-path coverage) added agent-channel-dispatch.test.ts (capability-gated on agents.deployment.supported + the seeded conformance-agent-channel-dispatch fixture + advertised replay mode via behaviorGate('openwop-deployment-channel-dispatch', …) — proves the §B pin from a REAL run graph, complementing agent-deployment-lifecycle.test.ts Leg 4's host-sample seam: a canonical POST /v1/runs of a node binding agent.channel:"stable" MUST record resolvedChannel + resolvedAgentVersion on agent.invocation.started (RFC 0077), a :fork{mode:"replay"} MUST re-read that recorded version, and the seam-guarded Leg 3 MOVES the channel then asserts a replay STILL carries the original pin — never re-resolving a moved channel; soft-skips by default, hard-fails under OPENWOP_REQUIRE_BEHAVIOR=true — the production-path proof of the §B contract). 2026-06-01 (RFC 0085 — openwop-agent-platform meta-profile, the Active→Accepted behavioral gate) added agent-platform-aggregate-evidence.test.ts (capability-gated on a host CLAIMING openwop-agent-platform in its live discovery profiles[] via behaviorGate('openwop-agent-platform', …) — the §C/§D honest-advertisement rule on the live /.well-known/openwop: the claim MUST satisfy the §B floor predicate (isAgentPlatformPartialpartial/full, never none), backed by the per-capability evidence not the profile string; OPENWOP_AGENT_PLATFORM_TIER=full forces the non-vacuous full bar — all governance terms + tenant installScope + all 16 §D terms; server-requiring, the always-on §B/§D derivation legs stay in agent-platform-profile.test.ts — the RFC 0085 → Accepted bar). 2026-06-01 (RFC 0084 — budget, quota + cost policy, the Active→Accepted behavioral gate) added budget-enforcement.test.ts (capability-gated on budget.supported via behaviorGate('openwop-budget-enforcement', …) — the §C/§D enforcement via the new POST /v1/host/sample/budget/run seam + the test event-log seam: a hard-cost-exhaust run emits the strict-ordered budget.reserved → budget.consumed → budget.threshold.crossed{percent} → budget.exhausted → cap.breached{kind:"budget-cost"} → run.failed{error:"budget_exhausted"} chain; a model-denied run is refused budget_model_denied BEFORE the provider call (fail-closed); an advisory host emits the budget.* events without stopping; every budget.* payload content-free backing budget-no-pricing-leak; new lib helper src/lib/budgetPolicy.ts; soft-skips on 404 — the RFC 0084 → Accepted bar). 2026-06-01 (RFC 0080 — agent memory capability reconciliation, the Active→Accepted behavioral gate) added memory-degraded-projection.test.ts (capability-gated on agents.manifestRuntime.supported + memory.supported via behaviorGate('openwop-memory-degraded', …) — the §C degraded-projection iff-contract on the NORMATIVE GET /v1/agents: a degraded inventory entry MUST carry memoryDegraded:true + a non-empty, unique degradedMemoryDimensions[] from the closed §A-name enum, a non-degraded entry MUST NOT, the inventory is non-empty, and the degraded branch runs non-vacuously when OPENWOP_DEGRADED_AGENT_ID names a known-degraded agent; black-box, no POST seam — the RFC 0080 → Accepted bar). This batch also documents the two RFC 0068 conformance seams (POST /v1/host/sample/memory/consolidate + .../commitment/fire) in host-sample-test-seams.md (the 0068 gated scenarios shipped in 1.14.0). 2026-06-01 (RFC 0034 — collector-side BYOK-canary inspection) added otel-collector-canary-inspection.test.ts (always-on server-free: stands up a real OtelCollector, POSTs synthetic OTLP/HTTP-JSON traces + metrics through its actual ingest path, and proves the new findCanaryLeakage() inspector catches a canary embedded in a span attribute / resource attribute / span name / metric data-point attribute while reporting ZERO hits on a redacted payload and never matching an empty canary — the non-vacuous proof that the conformance collector now inspects what the host's OTLP exporter ACTUALLY shipped over the wire, closing the secret-leakage-otel-attribute / -debug-bundle-otel collector-seam gap; the live capability-gated complement is the new collector-export describe block in secret-leakage-otel-attribute.test.ts). 2026-06-01 (RFC 0035 — sandbox wall-clock timeout, the 7th-of-8 graduation) added sandbox-wasm-timeout.test.ts (worker-driven server-free: probeTimeout in wasm-sandbox-probe.ts spawns a worker thread running the committed misbehaving-timeout.wasm + a main-thread kill-timer — the thread preemption a same-thread probe can't do — asserting sandbox_timeout with a well-behaved positive control; graduates node-pack-sandbox-timeout reference-impl→protocol, so 7 of 8 node-pack-sandbox-* invariants are now protocol-tier, only the JS-specific no-eval permanently exempt). 2026-05-31 (audit-response black-box / graduation batch) added three more: sandbox-wasm-isolation.test.ts (RFC 0035 — drives the committed fixtures/wasm-sandbox/*.wasm through wasm-sandbox-probe.ts: escape/capability-gate via static WebAssembly.Module.imports(), an OOB-store memory trap, double-instantiate isolation; 10/10; graduates 6 node-pack-sandbox-* invariants reference-impl→protocol), workspace-cross-tenant-isolation-blackbox.test.ts (RFC 0059 — two-credential black-box on the normative §C /v1/host/workspace/files endpoints: owner A writes, a second-tenant credential fails closed; no seam), and prompt-resolution-chain-event.test.ts (RFC 0029 — reads the durable agent.promptResolved.chain[] precedence record via the normative GET /v1/runs/{runId}/events/poll; no seam) — each the production-path proof that graduates its surface into the openwop-core-standard floor. 2026-05-31 (RFC 0088 — the openwop-core-standard Core Standard Profile, the audit-response Core Candidate target) added core-standard-profile.test.ts (always-on server-free derivation probe: isCoreStandard derives the §B floor — openwop-coreopenwop-interrupts ∧ (openwop-stream-sseopenwop-stream-poll) — a bare openwop-core host without interrupts is excluded, a host with no event transport fails, and the annex is absent from deriveProfiles because it composes rather than redefines). 2026-05-31 (RFC 0082 — agent deployment lifecycle, the Active→Accepted behavioral gate) added agent-deployment-lifecycle.test.ts (capability-gated on agents.deployment.supported via behaviorGate('openwop-deployment-lifecycle', …) — the §E promotion contract via the new POST /v1/host/sample/agents/deployment-transition seam + the test event-log seam across four legs: promote (authorize RFC 0049 → approvalGate RFC 0051 → eval-verify RFC 0081 → content-free deployment.promoted with a seven-state toState + toVersion, the record validating agent-deployment.schema.json), unauthorized (fail-closed — allowed:false, no deployment.promoted, the behavioral leg of deployment-promotion-fail-closed), eval-gate-unmet (eval_gate_unmet denial, §E-3), and channel-pin (the §B resolvedAgentVersion recorded-fact on agent.invocation.started); new lib helper src/lib/agentDeployment.ts; soft-skips on 404 — the RFC 0082 → Accepted bar). 2026-05-31 (RFC 0081 — agent evaluation, the Active→Accepted behavioral gate) added agent-eval-run.test.ts (capability-gated on agents.evalSuite.supported via behaviorGate('openwop-eval-run', …) — the §B mode:"eval" projection via the new POST /v1/host/sample/agents/eval-run seam + the test event-log seam: eval.started-first → one eval.scored per task → eval.completed-once ordering (count == eval.completed.taskCount), the content-free eval.scored legs (score ∈ 0..1) backing eval-summary-no-content-leak, and the NORMATIVE GET /v1/runs/{runId}/eval-summary schema-valid EvalSummary round-trip with passedCount <= taskCount; new lib helper src/lib/agentEval.ts; soft-skips on 404 — the RFC 0081 → Accepted bar). 2026-05-31 (RFC 0083 — durable trigger bridge, the Active→Accepted behavioral gate) added trigger-bridge-delivery.test.ts (profile-gated on openwop-trigger-bridge derived from the live discovery doc — the §C delivery model via the POST /v1/host/sample/trigger-bridge/deliver seam + the test event-log seam: dedup→effectively-once trigger.delivery.attempted{delivered} (§C-1), retry-exhaustion→{dead-lettered} + trigger.subscription.state.changed{toState:dead-lettered} (§C-2 + RFC 0053), and the delivered run's run.started.causationId == the delivery id (§C / RFC 0040); both trigger.* events content-free; the always-on shape stays in trigger-bridge-shape.test.ts; new lib helper src/lib/triggerBridge.ts). 2026-05-31 (RFC 0087 — agent org-chart, the Active→Accepted behavioral gate) added two capability-gated behavioral scenarios (both gated on agents.orgChart.supported, black-box on the normative /v1/agents/org-chart surface — no new POST seam): agent-org-chart-scoping.test.ts (the GET /v1/agents/org-chart tree-shape — departments form an acyclic parentDepartmentId tree, members reference host:<id> roster entries — + the §D responsibility roll-up via GET /v1/agents/org-chart/{departmentId} with a deduped responsibilities[] union + the RFC 0074 cross-tenant 404 via OPENWOP_CROSS_TENANT_ORG_CHART_DEPARTMENT_ID) and org-position-no-authority-escalation.test.ts (the behavioral leg of the protocol-tier invariant — the live org-chart wire carries NO authority-bearing field on any member/department/responsibility-view object; the structural leg stays always-on in agent-org-chart-shape.test.ts, and the deeper RFC 0049/0051 authority-invariance legs stay reference-impl tier per the agent-manifest-runtime no-host-hook precedent). 2026-05-31 (RFCs 0086 + 0077 — the Active→Accepted behavioral gate) added four capability-gated behavioral scenarios so a non-steward host can be mechanically certified non-vacuously under OPENWOP_REQUIRE_BEHAVIOR=true: agent-roster-attribution.test.ts (RFC 0086 §B/§C; gated on agents.roster.supported — the normative GET /v1/agents/roster read shape + total==roster.length, the §C roster.run.initiated-before-agent.invocation.started ordering, the content-free payload backing roster-attribution-no-content, the durable work-item triggerSubscriptionId, and the RFC 0074 cross-tenant 404 via OPENWOP_CROSS_TENANT_ROSTER_ID), agent-live-invocation-bracket.test.ts (RFC 0077 §E; gated on agents.liveRuntime.supportedagent.invocation.started-first / agent.invocation.completed-last bracket, matching invocationId, source/outcome closed enums, content-free), agent-live-structured-output.test.ts (RFC 0077 §B step 6; gated on agents.liveRuntime.structuredOutput — a result violating handoff.returnSchemaRef fails the invocation outcome:"failed" rather than shipping as completed), and agent-live-allowlist-enforced.test.ts (RFC 0077 §F-1 / RFC 0002 §A14; gated on agents.liveRuntime.supported — a tool outside toolAllowlist is not callable); all four drive the documented POST /v1/host/sample/roster/fire + POST /v1/host/sample/agents/live-invoke seams plus the test event-log seam and soft-skip on 404 (these are the RFC 0086 / 0077 Active→Accepted bars). 2026-05-30 (RFC 0087 — agent org-chart, Draft -> Active) added agent-org-chart-shape.test.ts (always-on server-free: the capabilities.agents.orgChart shape + the AgentOrgChart round-trip + the non-host: member negative + the §B structural non-authority guarantee — the schema rejects a scopes/canDispatch/permissions/authority field on a member (additionalProperties:false), and a member's key set is exactly {rosterId, departmentId, roleId, reportsTo} — backing the protocol-tier org-position-no-authority-escalation invariant; no new RunEventType). 2026-05-30 (RFC 0086 — standing agent roster, Draft -> Active) added agent-roster-shape.test.ts (always-on server-free: the capabilities.agents.roster shape + the AgentRosterEntry round-trip + the host: rosterId + agentRef version-XOR-channel negatives + the content-free roster.run.initiated negatives backing the protocol-tier roster-attribution-no-content invariant + the additive roster inventory projection + RunEventType-enum membership). 2026-05-30 (RFC 0082 — agent deployment lifecycle, Draft -> Active) added agent-deployment-shape.test.ts (always-on server-free: the capabilities.agents.deployment shape + the AgentDeployment record round-trip + the AgentRef channel XOR version not-clause + the four deployment.* payloads + the content-free negatives backing the protocol-tier deployment-event-no-content-leak invariant). 2026-05-30 (RFC 0085 — openwop-agent-platform meta-profile, Draft -> Active) added agent-platform-profile.test.ts (always-on server-free derivation of the operational-annex none/partial/full status: all-floor ⇒ partial, missing-flag ⇒ none, the replay-OR-nondeterminismPolicy.declared term, floor+governance ⇒ full, missing-tenant-scope ⇒ partial-not-full per the honest-advertisement rule, eval/deploy/budget-are-advisory-not-hard-terms, + the capabilities.nondeterminismPolicy.declared shape). 2026-05-30 (RFC 0084 — budget, quota + cost policy, Draft -> Active) added budget-policy-shape.test.ts (always-on server-free: budget-policy.schema.json round-trip + the §A orthogonality guard — a wall-time field is rejected (it's RFC 0058's runTimeoutMs) — + threshold/onExhaustion negatives + the four content-free budget.{reserved,consumed,threshold.crossed,exhausted} payloads + the four cap.breached{budget-*} kinds + RunEventType-enum membership + the no-pricing-property structural check backing the protocol-tier budget-no-pricing-leak invariant + the capabilities.budget/limits.maxBudget* shape). 2026-05-30 (RFC 0083 — durable trigger + channel bridge, Draft -> Active) added trigger-bridge-shape.test.ts (always-on server-free: trigger-subscription.schema.json round-trip + missing-state/out-of-enum-source/unknown-property negatives + the four-state vocab + the two content-free trigger.{subscription.state.changed,delivery.attempted} payloads incl. closed state/outcome enums + RunEventType-enum membership + the triggerBridge/webhooks.durable capability shape + the openwop-trigger-bridge profile derivation incl. the no-dead-letter-sink negative). 2026-05-30 (RFC 0079 — credential provenance + egress policy, Draft -> Active) added egress-provenance-shape.test.ts (always-on server-free: credential-provenance.schema.json round-trip + audiences:[]/missing-credentialId/unknown-property negatives + the no-secret-property structural check backing the protocol-tier egress-decision-no-secret-leak invariant + the content-free egress.decided record incl. the decision enum + RunEventType-enum membership + the httpClient.egressPolicy shape; the behavioral egress-credential-audience-bound confused-deputy MUST is reference-impl tier, deferred to a host). 2026-05-30 (RFC 0078 — portable tool catalog, Draft -> Active) added tool-descriptor-shape.test.ts (always-on server-free: tool-descriptor.schema.json round-trip + the §C-1 exechost-extension cross-field MUST (RFC 0069) + the safetyTier-required negative + additionalProperties:false, the capabilities.toolCatalog supported/sources/sessionLifecycle shape, and the two content-free tool.session.{opened,closed} payload $defs incl. the closed outcome enum + RunEventType-enum membership). 2026-05-30 (RFC 0080 — agent memory capability reconciliation, Draft -> Active) added memory-capability-model-shape.test.ts (always-on server-free: the additive capabilities.memory.{writable,search,retention} dimension shapes + malformed-instance negatives — retention.ttl non-boolean, out-of-enum search.modes, unknown property under additionalProperties:false — the agent-inventory-response memoryDegraded/degradedMemoryDimensions closed-enum fields, and the openwop-memory derivation surfacing for read/write + long-term hosts while withholding from writable:false). 2026-05-30 (RFC 0081 — agent evaluation, Draft -> Active) added agent-eval-suite-shape.test.ts (always-on server-free: the capabilities.agents.evalSuite shape + the AgentEvalSuite/EvalSummary schema round-trips + the three eval.{started,scored,completed} payloads + the content-free negatives — a task entry with a taskOutput body, a safetyFinding with an excerpt — backing the new eval-summary-no-content-leak SECURITY invariant). 2026-05-29 (RFC 0076 §B — ctx.http.safeFetch live-run audit) added safefetch-live-audit.test.ts (behaviorGate('openwop-safefetch-live-audit', …), gated on httpClient.safeFetch + toolHooks.prePostEvents) — asserts the audit-when-both MUST against the durable run event log via the new POST /v1/host/sample/http/safe-fetch-run open seam + the test event-log seam, closing the seam-vs-production gap (a production createSafeFetch() with no audit hooks passes the inline safefetch-behavior.test.ts but FAILS this under OPENWOP_REQUIRE_BEHAVIOR=true); this is the RFC 0076 §B → Accepted bar; run seam soft-skips on 404 (host-pending). 2026-05-29 (RFC 0066 — x-openwop-form picker UX hints, Draft → Active) added x-openwop-form-pack-manifest.test.ts (always-on server-free: an annotated configSchema stays a valid 2020-12 schema + the advisory hints don't change what it accepts, each §A annotation matches the shape, an unknown kind validates for forward-compat, 3 negatives — missing/non-string kind, non-string dependsOn). 2026-05-29 (RFC 0076 §B — ctx.http.safeFetch) added safefetch-behavior.test.ts (seam-gated: SSRF block / DNS-rebinding / Connection: upgrade refusal / tool-hooks audit-when-both, via POST /v1/host/sample/http/safe-fetch; advertisement contract stays in http-client-ssrf.test.ts). 2026-05-29 (RFC 0076 §A — pack runtime.requires[] install gate) added two: runtime-requires-shape.test.ts (server-free closed-vocabulary validation — the 8 tokens validate, a raw builtin name is rejected, empty-array≡omission, uniqueItems) + runtime-requires-install-gate.test.ts (seam-gated install-grant / install-refuse → pack_runtime_requirement_unmet / non-sandbox SHOULD-projection, soft-skip on 404 via POST /v1/host/sample/packs/install-gate). 2026-05-29 (RFC 0047 — host.oauth authorization-code roundtrip) added oauth-authorization-code-roundtrip.test.ts — capability-gated on capabilities.oauth.supported + grants including authorization_code; drives the POST /v1/host/sample/oauth/authorize-code-roundtrip seam against the one canonical synthetic provider in fixtures/oauth-providers/synthetic.json (soft-skip on 404, Tier-2 host-pending), asserting a successful grant returns a credential REFERENCE (token persisted as a host.credentials entry) and that the authorization code / state / PKCE verifier / acquired access+refresh tokens never appear on any run-visible surface (RFC 0047 §C + §C.2 / credential-payload-redaction). Closes the RFC 0047 Tier-2 gap (capability-shape + redaction scenarios existed; the actual authorization-code dance was unexercised). 2026-05-26 (RFC 0070 — agent-manifest runtime) added agent-manifest-runtime.test.ts; 2026-05-26 (RFC 0071 — artifact-type + chat card packs) added six: artifact-type-pack-manifest-validation.test.ts + artifact-schema-compile-bounded.test.ts (server-free) + artifact-type-pack-install.test.ts + artifact-type-store-without-render.test.ts + chat-card-pack-manifest-validation.test.ts (server-free) + chat-card-pack-execution.test.ts (capability-gated, host-pending). 2026-05-26 (RFCs 0067 / 0068 / 0069 — spec-gap Draft cohort) added five scenarios: byok-auth-modes.test.ts (RFC 0067; always-on schema-shape of aiProviders.authModes + a discovery-gated §B auth-mode-contract cross-field check), memory-consolidation-shape.test.ts (RFC 0068; always-on shape of agents.memoryConsolidation/agents.commitments + the agent.memory.consolidated/commitment.fired payload $defs), memory-consolidation-idempotent.test.ts + commitment-fired.test.ts (RFC 0068; capability-gated behavioral, soft-skip on the documented /v1/host/sample/memory/consolidate + /commitment/fire seams), and exec-not-protocol-tier.test.ts (RFC 0069; always-on server-free structural assertion that the protocol corpus defines no core.*/openwop.* exec-class primitive — backs the exec-must-not-be-protocol-tier SECURITY invariant). 2026-05-25 (RFC 0061 — stateful agent-loop lifecycle, executionModel.version 5) added four agent-loop-*.test.ts scenarios: -version5-shape (always-on; validates executionModel.statefulResume/transcriptWindow + the 1–5 version ceiling) plus -iteration-monotonic (gated on version >= 5; runOrchestrator.decided.iteration increments 1,2,3… exactly once per turn), -workspace-snapshot (gated additionally on host.workspace.supported; a turn-i workspace write is invisible to turn i, visible to turn i+1), and -stateful-resume (gated on statefulResume; a mid-loop suspend resumes at the same iteration without resetting the counter) — the three behavioral scenarios drive the documented agent-loop seam (POST /v1/host/sample/agentloop/run) and soft-skip until a host wires it. 2026-05-25 (RFC 0059 — host.workspace M2, reference-host enforcement) added two workspace-*.test.ts scenarios: -behavior (capability-gated CRUD round-trip / If-Match 409 workspace_conflict / workspace_too_large / §D run-start snapshot, all via the real /v1/host/workspace/files §C endpoints) and -cross-tenant-isolation (WCT-1 — drives the documented POST /v1/host/sample/workspace/op seam to assert a file owned by one {tenant, workspace} is unreadable, on both get and list, under a different owner; backs the new workspace-cross-tenant-isolation SECURITY invariant). The in-memory reference host now advertises capabilities.workspace.supported and honors §C/§D/§E end-to-end. 2026-05-25 (RFC 0062 — memory.distillation "dreams") added five distillation-*.test.ts scenarios: -shape (always-on; validates the capabilities.memory.distillation block + the additive distillation sub-object on memory.compacted) plus -token-budget (within budget tokensUsed ≤ tokenBudget; an un-meetable budget → token_budget_exceeded with no partial archive), -stable-archive (same sources + budget ⇒ byte-stable archive checksum), -index-roundtrip (gated additionally on indexEmitted; the MEMORY-INDEX.json workspace file is retrievable + workspace.updated fired), and -secret-carryforward (SR-1: a redacted source secret never appears in the archive) — the four behavioral scenarios drive the documented memory-distillation seam (POST /v1/host/sample/memory/distill) and soft-skip until a host wires it. 2026-05-25 (RFC 0063 — core.subWorkflow.outputAttestation) added four subrun-*.test.ts scenarios: -attestation-shape (always-on; validates the capabilities.agents.subRunAttestation flag) plus -checksum-stable (the child output checksum is the byte-stable, key-order-invariant RFC 8785 JCS + SHA-256 digest), -approval-gate (requireApprovalaccept merges, reject does not), and -approval-fail-closed (no accept/edit-accept → no merge; backs the deferred subrun-merge-approval-fail-closed invariant) — the three behavioral scenarios drive the documented sub-run attestation seam (POST /v1/host/sample/subrun/attest)