@openwop/openwop-conformance 2.45.22 → 2.45.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +227 -608
  3. package/coverage.md +118 -90
  4. package/dist/spec-artifacts.lock.json +2 -2
  5. package/fixtures/conformance-multi-party-council-oversize.json +244 -0
  6. package/fixtures/conformance-multi-party-council.json +61 -0
  7. package/fixtures/conformance-nondeterminism.json +23 -0
  8. package/fixtures/conformance-wasm-pack-memory-cap-breach.json +23 -5
  9. package/fixtures/frontend-plugin-packs/ui/narrow.html +4 -0
  10. package/fixtures/frontend-plugin-packs/ui-plugin-pack-narrow.json +16 -0
  11. package/fixtures/wasm-packs/build.mjs +43 -0
  12. package/fixtures/wasm-packs/misbehaving-abi/module.wasm +0 -0
  13. package/fixtures/wasm-packs/misbehaving-abi/module.wat +24 -0
  14. package/fixtures/wasm-packs/misbehaving-abi/pack.json +27 -0
  15. package/fixtures/wasm-packs/misbehaving-memory/module.wasm +0 -0
  16. package/fixtures/wasm-packs/misbehaving-memory/module.wat +30 -0
  17. package/fixtures/wasm-packs/misbehaving-memory/pack.json +27 -0
  18. package/fixtures.md +109 -55
  19. package/package.json +3 -3
  20. package/requirements.json +319 -75
  21. package/scenario-majors.json +17 -2
  22. package/schemas/CORPUS-STAMP.json +32 -30
  23. package/src/lib/council-roster-witness.ts +144 -0
  24. package/src/lib/effect-receiver.ts +12 -1
  25. package/src/lib/ui-plugin-boundary-witness.ts +180 -0
  26. package/src/lib/wasm-memory-cap-witness.ts +46 -0
  27. package/src/scenarios/v2-bound-id-path-projection.test.ts +20 -0
  28. package/src/scenarios/v2-envelope-contracts-advertisement.test.ts +8 -0
  29. package/src/scenarios/v2-multi-party-council.test.ts +56 -0
  30. package/src/scenarios/v2-nondeterminism-policy-advertisement.test.ts +11 -1
  31. package/src/scenarios/v2-nondeterminism-sources.test.ts +83 -0
  32. package/src/scenarios/v2-purpose-propagation-advertisement.test.ts +1 -1
  33. package/src/scenarios/v2-purpose-propagation-onward.test.ts +119 -0
  34. package/src/scenarios/v2-ui-plugin-boundary.test.ts +68 -0
  35. package/src/scenarios/v2-wasm-memory-cap.test.ts +34 -0
package/fixtures.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # OpenWOP Conformance Suite — Fixture Workflow Contract
2
2
 
3
- > **Status: FINAL v1 (2026-05-10).** Defines the standardized fixture workflows every OpenWOP-compliant server MUST seed before the conformance suite can exercise run-lifecycle, idempotency, stream-mode, interrupt, and replay scenarios. Stable surface for external review. Keywords MUST, SHOULD, MAY follow [RFC 2119](https://www.rfc-editor.org/rfc/rfc2119). Status legend per `../spec/v1/auth.md`.
3
+ > Defines the fixture workflows a host seeds so the conformance suite can exercise run lifecycle, idempotency, streaming, interrupts, replay and the other fixture-gated scenarios. RFC 2119 keywords (MUST, SHOULD, MAY) apply to hosts that seed these fixtures. Paths are written in v2 form (unversioned, [`spec/v2/core/versioning.md`](../spec/v2/core/versioning.md)); a v1 host serves the same operations under `/v1/`. `/v1/host/sample/...` paths below are the v1 host test seams; the v2 seams are in [`api/seams-v2.yaml`](../api/seams-v2.yaml).
4
4
 
5
5
  ---
6
6
 
@@ -8,16 +8,16 @@
8
8
 
9
9
  Run-lifecycle conformance tests need a stable target — a workflow whose `workflowId`, expected events, and terminal status are agreed in advance. Without this, every implementation defines its own test workflows and the conformance suite can't run cross-implementation.
10
10
 
11
- This document defines a small set of fixture workflows whose canonical definitions live alongside the conformance suite (`fixtures/*.json`). An OpenWOP-compliant server MUST seed these fixtures into its workflow store before running the conformance suite against itself.
11
+ This document defines the fixture workflows whose canonical definitions live alongside the conformance suite (`fixtures/*.json`). A host MUST seed the fixtures its advertised scenarios need into its workflow store before running the suite against itself.
12
12
 
13
13
  ---
14
14
 
15
15
  ## Seeding contract
16
16
 
17
- An OpenWOP-compliant server MUST:
17
+ A host that seeds the fixtures MUST:
18
18
 
19
19
  1. Accept the canonical JSON fixture definitions in `fixtures/*.json` verbatim (they validate against `../schemas/workflow-definition.schema.json`).
20
- 2. Persist each fixture under its declared `id` so that subsequent `GET /v1/workflows/{id}` returns the seeded definition.
20
+ 2. Persist each fixture under its declared `id` so that a subsequent `GET /workflows/{workflowId}` (`getWorkflow`) returns the seeded definition.
21
21
  3. Treat seeding as idempotent — running the seeder repeatedly MUST NOT produce duplicate runs, error states, or version drift.
22
22
  4. Expose the seeded fixtures to runs created with the conformance suite's API key.
23
23
 
@@ -36,13 +36,14 @@ Servers MUST NOT require fixtures to be re-uploaded on every conformance run —
36
36
  All fixtures MUST advertise:
37
37
 
38
38
  - **`workflowId`** — exact string clients use to start runs
39
- - **Trigger** — must be `manual` so the conformance suite can call `POST /v1/runs` without channel-specific setup
39
+ - **Trigger** — must be `manual` so the conformance suite can call `POST /runs` (`createRun`) without channel-specific setup
40
40
  - **Inputs** — schema declared via `variables[]`
41
41
  - **Expected behavior** — terminal status, expected event types, timing bounds
42
42
 
43
43
  | Fixture | `workflowId` | Purpose | Terminal status | Bounded duration |
44
44
  | ----------------------------------------- | ----------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- | ---------------------------- |
45
45
  | Noop | `conformance-noop` | Cheapest possible run-lifecycle test | `completed` | ≤ 5s |
46
+ | Nondeterminism Sources | `conformance-nondeterminism` | RFC 0237 §D — one `core.conformance.nondeterminism` node draws one value per source the host lists in `nondeterminismPolicy.sources` into the run outputs; a `replay` fork from `fromSeq: 0` MUST reproduce each | `completed`; replay outputs byte-equal per listed source | ≤ 10s |
46
47
  | Identity | `conformance-identity` | Verifies input/output passthrough | `completed` | ≤ 5s |
47
48
  | Delay | `conformance-delay` | Verifies poll/SSE behavior over time | `completed` | ≤ 30s (input-controlled) |
48
49
  | Failure | `conformance-failure` | Verifies error-event surface | `failed` | ≤ 5s |
@@ -80,13 +81,13 @@ All fixtures MUST advertise:
80
81
  | Agent Pack Export | `conformance-agent-pack-export` | Phase 2 — workspace agents project to AgentManifest at `GET /v1/packs/export` | `completed` | ≤ 5s |
81
82
  | Agent Pack Provenance | `conformance-agent-pack-provenance` | Phase 2 — `sourceManifestId` provenance round-trip | `completed` | ≤ 10s |
82
83
  | Agent Pack Handoff Schema Validation | `conformance-agent-pack-handoff-schema-validation` | Phase 2 / HV-1 — host validates dispatch payloads against `handoff.taskSchemaRef` AND return payloads against `handoff.returnSchemaRef` per RFC 0003 §D. Three branches: valid-task → `completed`; invalid-task → `failed` with structured violation; mock-return-violation → violation surfaced before persistence. | varies by scenario | ≤ 5s |
83
- | WorkflowVariable format advisory | `conformance-workflow-variable-format-advisory` | RFC 0136 req 3 — a variable declares `format: "email"` with an off-format `defaultValue`; `format` is advisory, so the run MUST complete (a value/format mismatch MUST NOT fail the run). Run via `POST /v1/runs` (portable pre-registered pattern). `workflow-variable-format.test.ts` leg B2. | `completed` | ≤ 5s |
84
+ | WorkflowVariable format advisory | `conformance-workflow-variable-format-advisory` | RFC 0136 req 3 — a variable declares `format: "email"` with an off-format `defaultValue`; `format` is advisory, so the run MUST complete (a value/format mismatch MUST NOT fail the run). Run via `POST /runs` (portable pre-registered pattern). `workflow-variable-format.test.ts` leg B2. | `completed` | ≤ 5s |
84
85
  | Dispatch Input Mapping | `conformance-dispatch-input-mapping` | RFC 0022 §A / HVMAP-1a — host honors `inputMapping` on `core.dispatch`. Capability-gated on `capabilities.agents.dispatchMapping`. | `completed` | ≤ 5s |
85
86
  | Dispatch Output Mapping | `conformance-dispatch-output-mapping` | RFC 0022 §A / HVMAP-1b — host harvests child variables via `outputMapping` on `core.dispatch`. Capability-gated on `capabilities.agents.dispatchMapping`. | `completed` | ≤ 5s |
86
87
  | Dispatch Cross-Worker Handoff | `conformance-dispatch-cross-worker-handoff` | RFC 0022 §A / HVMAP-1c — sequential fan-out: child-a writes via `perWorkerOutputMappings`, child-b reads via `perWorkerInputMappings`. Capability-gated on `capabilities.agents.dispatchMapping`. | `completed` | ≤ 10s |
87
88
  | subWorkflow Input Mapping | `conformance-subworkflow-input-mapping` | RFC 0022 §B / HVMAP-2 — host honors `inputMapping` on `core.subWorkflow`; overrides matching `defaultValue` declarations on the child. Capability-gated on `capabilities.subWorkflow.inputMapping`. | `completed` | ≤ 10s |
88
- | subWorkflow Input Mapping (child) | `conformance-subworkflow-input-mapping-child` | RFC 0022 §B / HVMAP-2 — child workflow for the input-mapping scenario. Declares `receivedPrdId.defaultValue='baked-in'`; parent's `inputMapping` MUST override that default. Single noop node; final variables read via `GET /v1/runs/{runId}` for the assertion. | `completed` | ≤ 5s |
89
- | Dispatch Input Mapping (child) | `conformance-dispatch-input-mapping-child` | RFC 0022 §A / HVMAP-1a — child workflow for the dispatch input-mapping scenario. Single noop node; the scenario reads this child's `inputs_json` via `GET /v1/runs/{childRunId}` and asserts `inputs.childGreeting === 'Alice'`. | `completed` | ≤ 5s |
89
+ | subWorkflow Input Mapping (child) | `conformance-subworkflow-input-mapping-child` | RFC 0022 §B / HVMAP-2 — child workflow for the input-mapping scenario. Declares `receivedPrdId.defaultValue='baked-in'`; parent's `inputMapping` MUST override that default. Single noop node; final variables read via `GET /runs/{runId}` for the assertion. | `completed` | ≤ 5s |
90
+ | Dispatch Input Mapping (child) | `conformance-dispatch-input-mapping-child` | RFC 0022 §A / HVMAP-1a — child workflow for the dispatch input-mapping scenario. Single noop node; the scenario reads this child's `inputs_json` via `GET /runs/{childRunId}` and asserts `inputs.childGreeting === 'Alice'`. | `completed` | ≤ 5s |
90
91
  | Dispatch Output Mapping (child) | `conformance-dispatch-output-mapping-child` | RFC 0022 §A / HVMAP-1b — child workflow for the dispatch output-mapping scenario. Declares `childOutcome.defaultValue='done'`; on terminal, parent's `outputMapping` harvests `childOutcome → parentResult`. | `completed` | ≤ 5s |
91
92
  | Dispatch Cross-Worker Handoff (child-a) | `conformance-dispatch-cross-worker-handoff-child-a` | RFC 0022 §A / HVMAP-1c — first child of the cross-worker-handoff scenario. Declares `output.defaultValue='hello'`; on terminal, parent's `perWorkerOutputMappings.child-a` harvests `output → sharedVar`. | `completed` | ≤ 5s |
92
93
  | Dispatch Cross-Worker Handoff (child-b) | `conformance-dispatch-cross-worker-handoff-child-b` | RFC 0022 §A + §D / HVMAP-1c — second child of the cross-worker-handoff scenario. Sequential fan-out — runs after child-a; receives parent's `sharedVar` via `perWorkerInputMappings.child-b` onto its `input` input. Scenario reads child-b's `inputs_json` to assert `inputs.input === 'hello'`. | `completed` | ≤ 5s |
@@ -96,7 +97,7 @@ All fixtures MUST advertise:
96
97
  | subWorkflow Mid-Run Mutation (child) | `conformance-subworkflow-mid-run-mutation-child` | RFC 0022 §B / HVMAP-2-no-midrun-propagation — child workflow with a `core.approvalGate` that suspends so the parent can mutate its variable bag mid-run. Declares `receivedPrdId.defaultValue='baked-in'` (overridden at dispatch by inputMapping). | `completed` | ≤ 30s |
97
98
  | Dispatch Per-Worker Mapping Override | `conformance-dispatch-per-worker-override` | RFC 0022 §A / HVMAP-1c-override — parent with BOTH a default `inputMapping` (`{ input: 'defaultX' }`) AND `perWorkerInputMappings.child-b: { input: 'sharedVar' }`. Verifies `effectiveInputMapping` precedence per §A: child-a receives the default, child-b receives the override. Reuses `conformance-dispatch-cross-worker-handoff-child-a` + `-child-b`. | `completed` | ≤ 30s |
98
99
  | Dispatch deterministic-fail child | `conformance-dispatch-deterministic-fail-child` | RFC 0022 §B / HVMAP-1b-failed — child workflow that ALWAYS terminates `failed` via `core.fail`. Used by `conformance-dispatch-output-mapping` to verify the parent's `outputMapping` is SKIPPED when the child fails terminally. | `failed` | ≤ 5s |
99
- | Dispatch cancellable child | `conformance-dispatch-cancellable-child` | RFC 0022 §B / HVMAP-1b-cancelled — child workflow with a long `core.delay` so the test cancels it externally via `POST /v1/runs/{childRunId}/cancel`. Verifies the parent's `outputMapping` is SKIPPED when the child terminates `cancelled`. | `cancelled` | ≤ 60s |
100
+ | Dispatch cancellable child | `conformance-dispatch-cancellable-child` | RFC 0022 §B / HVMAP-1b-cancelled — child workflow with a long `core.delay` so the test cancels it externally via `POST /runs/{childRunId}/cancel`. Verifies the parent's `outputMapping` is SKIPPED when the child terminates `cancelled`. | `cancelled` | ≤ 60s |
100
101
  | Multi-Agent Handoff (parent) | `conformance-multi-agent-handoff` | RFC 0037 (`version: 1`) — exercises the planner→worker handoff state machine. Supervisor decides one `next-worker`, dispatch spawns the child, harvests outputMapping. Conformance reads the event log for the 4 `core.workflowChain.event` transition records in causation-chained order (`dispatch.began → dispatch.succeeded → child.completed → output.harvested`). Capability-gated on `capabilities.multiAgent.executionModel.supported`. | `completed` | ≤ 30s |
101
102
  | Multi-Agent Handoff (child) | `conformance-multi-agent-handoff-child` | RFC 0037 (`version: 1`) — child for `conformance-multi-agent-handoff`. Declares `childOutcome.defaultValue='handoff-complete'`; the parent's outputMapping harvests it onto `parentResult`, triggering the `output.harvested` transition event. | `completed` | ≤ 5s |
102
103
  | Multi-Agent Confidence Escalation | `conformance-multi-agent-confidence-escalation` | RFC 0039 §A (`version: 2`) — exercises the confidence-floor escalation contract. Supervisor's `mockDispatchPlan` carries ONE decision with `confidence: 0.3` (below the 0.5 spec floor). The host MUST emit `core.workflowChain.confidence-escalated` AND suspend with a clarification interrupt BEFORE any dispatch.began fires; conformance asserts zero `core.workflowChain.event` records (no dispatch). Capability-gated on `capabilities.multiAgent.executionModel.version >= 2`. | `waiting-clarification` | ≤ 30s |
@@ -108,6 +109,8 @@ All fixtures MUST advertise:
108
109
  | Context-Budget Multi-Turn | `conformance-context-budget-multiturn` | RFC 0111 — **superseded as the witness gate in suite 2.41.0.** Drives the supervisor through `mockDecisions`, i.e. a mock supervisor — exactly what RFC 0111 §Scope forbids from advertising `contextBudget`, so no honest host can witness against it. Kept (v1 compatibility: hosts may still list it); both RFC 0111 scenarios now gate on `conformance-context-budget-live` | `completed` | ≤ 60s |
109
110
  | Context-Budget Live Orchestrator | `conformance-context-budget-live` | RFC 0111 witness (suite 2.41.0) — `core.orchestrator.supervisor` driven by the host's LIVE model (no mock keys; `config.instructions` is the objective), dispatching `conformance-noop` until it terminates, bounded by `settings.maxLoopbackIterations: 8`. The host reports each iteration's fed transcript through `GET /v1/host/sample/agent/transcript-window` including `entries[] { eventId, rendered }`; `context-budget-transcript-bound` recounts `chars`, checks real events + the recent tail + budget PRESSURE (no pressure ⇒ `partial-witness`); `context-summarization-replay` replays and compares the fed summary text byte for byte. A host whose supervisor has no live model MUST NOT advertise this fixture | `completed` | ≤ 300s |
110
111
  | Conversation Lifecycle | `conformance-conversation-lifecycle` | Phase 4 — open → exchange → close event ordering | `completed` | ≤ 20s |
112
+ | Multi-Party Council | `conformance-multi-party-council` | RFC 0239 §E.1 — a `core.conversationGate` with a three-member `participants` roster and `mockAutoResume: false`. `conversation.opened` carries the roster; a resumed turn from a non-member is refused `422 conversation_speaker_not_participant` and left unconsumed, then a member's turn resolves it. A host advertises it in `fixtures` when it can run it (RFC 0003) | `completed` | ≤ 20s |
113
+ | Multi-Party Council (oversize) | `conformance-multi-party-council-oversize` | RFC 0239 §E.2 — the same gate with a 64-member roster. A host advertising `multiPartyConversation.maxParticipants` below 64 refuses run creation `422 conversation_roster_exceeded` and opens no conversation | refused at creation | — |
111
114
  | Conversation vs Clarification | `conformance-conversation-vs-clarification` | Phase 4 — conversation suspend emits `conversation.*`, NOT `clarification.*` | `completed` | ≤ 15s |
112
115
  | Conversation Replay | `conformance-conversation-replay` | Phase 4 — `:fork` preserves conversation channel projection | `completed` | ≤ 30s |
113
116
  | Conversation Capability Negotiation | `conformance-conversation-capability-negotiation` | Phase 4 — INVERTED gate: hosts without `conversationPrimitive: true` MUST refuse | `failed` / refusal | ≤ 5s |
@@ -123,7 +126,7 @@ All fixtures MUST advertise:
123
126
  | A2A Task Roundtrip | `conformance-a2a-task-roundtrip` | Track 6 — host consumes the conformance suite's synthetic A2A peer; covers drift points #3 (`AUTH_REQUIRED`) and #4 (`REJECTED`). Node `core.conformance.a2a-invoke` is a **conformance-RESERVED** typeId (renamed 2026-08-16 from `core.a2a.invoke`, a multi-segment `core.*` id no host shipped and the corpus never defined): a host that consumes A2A peers MUST map it to its A2A bridge node (a host-extension node — `a2a-integration.md` §"State projection"); a host that does not consume A2A MUST NOT advertise this fixture | `failed` or `waiting-input` (per `driftScenario` input) | ≤ 30s |
124
127
  | WASM Pack Roundtrip | `conformance-wasm-pack-roundtrip` | RFC 0008 — invokes `vendor.openwop.rust-hello.greet` (loaded WASM pack); exercises required exports + at least one import | `completed` | ≤ 10s |
125
128
  | WASM Pack Memory-Cap Breach | `conformance-wasm-pack-memory-cap-breach` | RFC 0008 §K — invokes the deliberately-misbehaving `vendor.openwop.misbehaving.memory-bomb` pack (allocates 1 GiB beyond the host's `memoryPagesMax`). Host MUST emit `cap.breached` with `kind: "wasm-memory"` and drive the run to terminal `failed`. Misbehaving pack lives at `openwop-examples:examples/packs/rust-misbehaving-memory/` (repo-qualified per the 2026-06 monorepo split — the `openwop-examples` sibling repo) and is fixture-only (NOT signed for registry publication). | `failed` (with `cap.breached`) | ≤ 10s |
126
- | Configurable Schema | `conformance-configurable-schema` | Track 13 — workflow declares `configurableSchema` (`additionalProperties: false`, `recursionLimit: integer ≥ 1`). Suite verifies `GET /v1/workflows/{id}` surfaces the schema AND `POST /v1/runs` with a mismatched `configurable` returns `validation_error`. | `completed` (with accepted overlay) | ≤ 5s |
129
+ | Configurable Schema | `conformance-configurable-schema` | Track 13 — workflow declares `configurableSchema` (`additionalProperties: false`, `recursionLimit: integer ≥ 1`). Suite verifies `GET /workflows/{id}` surfaces the schema AND `POST /runs` with a mismatched `configurable` returns `validation_error`. | `completed` (with accepted overlay) | ≤ 5s |
127
130
  | Smoke — BYOK Roundtrip | `openwop-smoke-byok-roundtrip` | End-to-end BYOK secret-resolution smoke. Single `conformance.secret.echo` node fetches the host-provisioned canary secret `openwop-conformance-canary-secret`, emits SHA-256 hex + byte length to variables — never the raw value. Spec: `run-options.md` §"Credential references" + `auth.md` §"Secret resolution" + `observability.md` §"Redaction". | `completed` | ≤ 10s |
128
131
  | Secrets — Run Witness | `openwop-secrets-run-witness` | RFC 0229 §C — one `core.secret.witness` node. The client supplies a value with the run (`runSecrets`, a `run:` ref) and its SHA-256 as an input; the node outputs only `{ matched }`. It can confirm only a value the caller already holds, so it is safe to advertise in production. Advertised by every host that advertises `secrets.runSecrets`. | `completed` (`matched: true` or `false`); `failed` (`credential_forbidden` / `credential_not_found`) on the scope legs | ≤ 10s |
129
132
  | Secret — resolve then fail | `conformance-secret-resolve-then-fail` | `host-services.md` §`secrets` — resolves the byok canary exactly as `openwop-smoke-byok-roundtrip`, then `core.fail` fails the run; the canary MUST appear on no surface of the failed run | `failed` | ≤ 10s |
@@ -142,15 +145,23 @@ All fixtures MUST advertise:
142
145
  | Phase 4 Replay Divergence | `conformance-phase4-replay-divergence` | RFC 0041 §B — single `core.ai.structuredOutput` node against mock provider. Conformance scenario pre-seeds a 2-entry program via the existing mock-AI program seam: entry [0] returns a valid envelope (original run consumes); entry [1] returns `stopReason: 'safety'` + `refusalText` (`:fork mode: replay` consumes). Phase 4 hosts advertising `multiAgent.executionModel.replayDeterminism.refusalDivergenceEmission: true` MUST emit `replay.divergedAtRefusal` + fail replay with `error.code: 'replay_diverged_at_refusal'`. Silent substitution is non-conformant. Pairs with `replay-divergence-at-refusal.test.ts`. | original: `completed`; replay: `failed` (`error.code='replay_diverged_at_refusal'`) | ≤ 10s |
143
146
  | Phase 4 Nondeterministic Tool | `conformance-phase4-nondet-tool` | RFC 0041 §C — two-node workflow (`core.noop` proxied as a nondeterministic tool → `core.ai.structuredOutput`). Used by `replay-observable-sequence-determinism.test.ts` to verify that across original + replay runs, the observable `RunEventDoc` sequence prefix is identical up to and including the nondeterministic-tool node's `node.completed` event. The host's replay path MUST replay the original event log entries (rather than re-executing the tool) for nodes whose `core.tool.*` config carries `nondeterministic: true`. Phase 4 hosts advertising `multiAgent.executionModel.replayDeterminism.supported: true` honor this contract. | original + replay: `completed`; observable prefixes equal up to the nondet boundary | ≤ 10s |
144
147
 
145
- The `messages`-mode stream fixture (AI token streaming) is covered by the deterministic mock-provider surface in `spec/v1/run-options.md`. Hosts that do not advertise `Capabilities.testing.mockProviders` skip-equivalent on those scenarios.
148
+ The `messages`-mode stream fixture (AI token streaming) is covered by the deterministic mock-provider surface (`spec/v1/run-options.md` at v1; `testing.mockProviders` in [`spec/v2/core/runs.md`](../spec/v2/core/runs.md) at v2). Hosts that do not advertise `Capabilities.testing.mockProviders` skip-equivalent on those scenarios.
146
149
 
147
150
  ---
148
151
 
149
152
  ## Per-fixture contracts
150
153
 
154
+ ### `conformance-nondeterminism`
155
+
156
+ - **Purpose**: verify RFC 0237 §B — a value drawn from a source the host lists in `nondeterminismPolicy.sources` is recorded where it is read, and a `replay` fork reproduces it.
157
+ - **Shape**: one node, `draw` (`core.conformance.nondeterminism`).
158
+ - **`core.conformance.nondeterminism` is a conformance-RESERVED typeId** (same pattern as `core.conformance.side-effect`): a host listing `sources` maps it to a node that, for each listed source, draws one value and writes it to the run's outputs under the source's name: `clock` an RFC 3339 time, `random` and `id` the drawn value as a string, `env` a configuration value of the host's choosing, an `x-*` source a string.
159
+ - **Expected behavior**: the run reaches `completed`, and `run.completed.outputs` carries one string per listed source. A `replay` fork with `fromSeq: 0` reaches `completed` with byte-equal outputs for every listed source.
160
+ - **Advertise only if** the host lists `nondeterminismPolicy.sources` and records the drawn values. Consumed by `v2-nondeterminism-sources`.
161
+
151
162
  ### `conformance-noop`
152
163
 
153
- - **Purpose**: cheapest run-lifecycle test. Used by the conformance suite's `runs.test.ts` to verify create/read/terminal-event/cleanup work end-to-end.
164
+ - **Purpose**: cheapest run-lifecycle test. Used by `runs-lifecycle.test.ts` (v1) and `v2-created-run-readable.test.ts` (v2), and by most run-surface scenarios, to verify create, read and the terminal event end-to-end.
154
165
  - **Inputs**: none.
155
166
  - **Expected events** (in order, `updates` mode):
156
167
  1. `run.started`
@@ -172,7 +183,7 @@ The `messages`-mode stream fixture (AI token streaming) is covered by the determ
172
183
  - **Purpose**: verify the engine handles in-flight runs (status transitions over time, SSE keep-alives, poll fallback).
173
184
  - **Inputs**:
174
185
  - `delayMs` (integer, required, 0 ≤ value ≤ 30000) — server MUST sleep for this duration before completing.
175
- - **Expected behavior**: `GET /v1/runs/{runId}` MUST return `status: "running"` while the delay is in flight; `status: "completed"` after.
186
+ - **Expected behavior**: `GET /runs/{runId}` MUST return `status: "running"` while the delay is in flight; `status: "completed"` after.
176
187
  - **Terminal status**: `completed`.
177
188
 
178
189
  ### `conformance-failure`
@@ -194,7 +205,7 @@ The `messages`-mode stream fixture (AI token streaming) is covered by the determ
194
205
  1. Run starts and reaches an `approvalGate` node that calls `ctx.interrupt({kind: 'approval', ...})`.
195
206
  2. Server emits `interrupt.requested` (and SHOULD also emit `approval.requested` for back-compat).
196
207
  3. Run status MUST be `waiting-approval`.
197
- 4. After client POSTs `{action: 'accept'}` to `/v1/runs/{runId}/interrupt`, server emits `approval.received` and resumes.
208
+ 4. After the client POSTs `{action: 'accept'}` to `/runs/{runId}/interrupts/{nodeId}` (`resolveInterruptByRun`), server emits `approval.received` and resumes.
198
209
  5. Run reaches `completed`.
199
210
  - **Terminal status (after accept)**: `completed`.
200
211
  - **Terminal status (after reject, major 2)**: `failed`, with `error.code` `approval_rejected` on the snapshot and on `run.failed`, and `failedNodeId: "gate"`. The fixture has no edges, so nothing routes the failure (`spec/v2/core/interrupt.md` §Rejection, RFC 0223; `v2-approval-reject-disposition.test.ts`).
@@ -299,20 +310,20 @@ The `messages`-mode stream fixture (AI token streaming) is covered by the determ
299
310
  - **Inputs**:
300
311
  - `nonce` (string, required) — caller-supplied; server MUST NOT use this for any side effect, only for de-duplication semantics tests.
301
312
  - **Expected behavior**:
302
- - `POST /v1/runs` with the same `Idempotency-Key` and same body twice → second response MUST replay the first (`openwop-Idempotent-Replay: true` header) and MUST NOT create a second run.
313
+ - `POST /runs` with the same `Idempotency-Key` and same body twice → second response MUST replay the first (`openwop-Idempotent-Replay: true` header) and MUST NOT create a second run.
303
314
  - Same `Idempotency-Key` with a different body → 409.
304
315
  - **Terminal status**: `completed`.
305
316
 
306
317
  ### `conformance-cancellable`
307
318
 
308
- - **Purpose**: verify `:cancel` mid-run.
319
+ - **Purpose**: verify cancellation mid-run.
309
320
  - **Inputs**:
310
321
  - `delayMs` (integer, required, 1 ≤ value ≤ 60000) — wait long enough for the conformance test to issue cancel.
311
322
  - **Expected behavior**:
312
323
  1. Run reaches `running`.
313
- 2. Client posts `POST /v1/runs/{runId}:cancel`.
324
+ 2. Client posts `POST /runs/{runId}/cancel` (`cancelRun`).
314
325
  3. Server emits `run.cancelled` within 5s.
315
- 4. Subsequent `GET /v1/runs/{runId}` MUST return `status: "cancelled"`.
326
+ 4. Subsequent `GET /runs/{runId}` MUST return `status: "cancelled"`.
316
327
 
317
328
  ### `conformance-replay-ordinal-loop`
318
329
 
@@ -363,7 +374,7 @@ The `messages`-mode stream fixture (AI token streaming) is covered by the determ
363
374
  - **Topology**: two nodes: `core.orchestrator.supervisor` and `core.dispatch`, looping back to each other.
364
375
  - **Inputs**: none.
365
376
  - **Conformance test driver**:
366
- 1. POST `/v1/runs` with `{workflowId: "conformance-dispatch-loop"}`.
377
+ 1. POST `/runs` with `{workflowId: "conformance-dispatch-loop"}`.
367
378
  2. The orchestrator node must emit `runOrchestrator.decided` with `next-worker` then `terminate`.
368
379
  3. Poll until terminal.
369
380
  4. **Assert** terminal status is `completed`.
@@ -385,18 +396,18 @@ The `messages`-mode stream fixture (AI token streaming) is covered by the determ
385
396
 
386
397
  ## `conformance-version-fold` (closes F5)
387
398
 
388
- - **Consuming scenario**: `conformance/src/scenarios/version-fold.test.ts` (added 2026-06-11; previously this fixture had no consuming scenario).
399
+ - **Consuming scenario**: `conformance/src/scenarios/version-fold.test.ts`. **v1 only**: `X-Force-Engine-Version` is not a v2 header ([`spec/v2/core/headers.md`](../spec/v2/core/headers.md)).
389
400
  - **Purpose**: verify forward-compat fold-best-effort tolerance across the spec's engine-version cross-version interop matrix (`version-negotiation.md` §Cross-version interop matrix). Uses the test-keys-only `X-Force-Engine-Version` header to drive the same workflow at three different engine versions from a single deployed server — no multi-version fleet needed.
390
401
  - **Fixture topology**: a single `core.noop` node. The workflow itself is trivial; the test exercises the server's READ path (projection, event-log fold) under each forced engine version.
391
402
  - **Inputs**: none.
392
403
  - **Conformance test driver**:
393
404
  1. Read the server's `Capabilities.testing.forceEngineVersionRange = { min, max }`.
394
405
  2. For each version `v` in `[min, current, max]` (deduped):
395
- - POST `/v1/runs` with body `{workflowId: "conformance-version-fold"}` AND header `X-Force-Engine-Version: v`. Use a test API key.
406
+ - POST `/runs` with body `{workflowId: "conformance-version-fold"}` AND header `X-Force-Engine-Version: v`. Use a test API key.
396
407
  - Poll until terminal.
397
408
  - **Assert** terminal status is `completed`.
398
- - **Assert** `GET /v1/runs/{runId}` returns a valid `RunSnapshot` (the projection tolerates the version mismatch via fold-best-effort).
399
- - **Assert** `GET /v1/runs/{runId}/events/poll?lastSequence=0&timeout=1` returns a non-empty `events[]` array (event log is readable).
409
+ - **Assert** `GET /runs/{runId}` returns a valid `RunSnapshot` (the projection tolerates the version mismatch via fold-best-effort).
410
+ - **Assert** `GET /runs/{runId}/events/poll?lastSequence=0&timeout=1` returns a non-empty `events[]` array (event log is readable).
400
411
  - **Negative paths**:
401
412
  - Same fixture with a production API key returns `403 force_engine_version_forbidden`.
402
413
  - Same fixture with `X-Force-Engine-Version: <out-of-range>` returns `400 unsupported_force_engine_version`.
@@ -413,7 +424,7 @@ This fixture closes F5 without requiring any new server-side test infrastructure
413
424
  - **Fixture topology**: a single `core.ai.callPrompt` (or similar AI-bearing typeId) node. The node's actual prompt content is irrelevant — the conformance driver intercepts the AI dispatch via `configurable.mockProvider`.
414
425
  - **Inputs**: none.
415
426
  - **Conformance test driver**:
416
- 1. POST `/v1/runs` with body:
427
+ 1. POST `/runs` with body:
417
428
 
418
429
  ```jsonc
419
430
  {
@@ -434,7 +445,7 @@ This fixture closes F5 without requiring any new server-side test infrastructure
434
445
 
435
446
  Use a test API key (server returns 403 on production keys per `run-options.md` §Authorization).
436
447
 
437
- 2. Subscribe to `/v1/runs/{runId}/events?streamMode=messages`.
448
+ 2. Subscribe to `/runs/{runId}/events?streamMode=messages`.
438
449
  3. **Assert** chunk arrival order: `["Hello", " ", "world", "!"]` — same order as `tokens`.
439
450
  4. **Assert** the final chunk has `isLast: true`, `meta.finishReason === "stop"`, `meta.usage.completionTokens === 4`.
440
451
  5. **Assert** SSE stream closes on terminal — server-closed, not timeout.
@@ -484,7 +495,7 @@ The fixture JSONs and matching `subworkflow.test.ts` are part of the current con
484
495
  - **Topology**: 10 sequential `core.noop` nodes (`a → b → c → … → j`). A run completes naturally if no per-run override is supplied. With `configurable.recursionLimit = 5`, the run MUST trip after the 5th node.
485
496
  - **Inputs**: none.
486
497
  - **Conformance test driver**:
487
- 1. POST `/v1/runs` with `{workflowId: "conformance-cap-breach", configurable: {recursionLimit: 5}}`.
498
+ 1. POST `/runs` with `{workflowId: "conformance-cap-breach", configurable: {recursionLimit: 5}}`.
488
499
  2. Server SHOULD validate `recursionLimit ≤ Capabilities.limits.maxNodeExecutions`. If `maxNodeExecutions` is `100` (default), `5` is fine.
489
500
  3. Poll until terminal.
490
501
  4. **Assert** terminal status is `failed`.
@@ -509,7 +520,7 @@ Both items are tracked as v1.x conformance expansion work.
509
520
  - **Topology**: single `core.delay` node that sleeps `input.delayMs` (default `30000`) — far longer than the small `runTimeoutMs` the test supplies.
510
521
  - **Inputs**: `delayMs` (number, default `30000`).
511
522
  - **Conformance test driver**:
512
- 1. POST `/v1/runs` with `{workflowId: "conformance-run-duration-breach", configurable: {runTimeoutMs: 1000}}`.
523
+ 1. POST `/runs` with `{workflowId: "conformance-run-duration-breach", configurable: {runTimeoutMs: 1000}}`.
513
524
  2. Poll until terminal.
514
525
  3. **Assert** terminal status is `failed`.
515
526
  4. **Assert** `RunSnapshot.error.code === "run_timeout"`.
@@ -527,7 +538,7 @@ This fixture is unblocked when a host exposes a wall-clock deadline enforcer adv
527
538
  - **Purpose**: verify the BYOK secret-resolution roundtrip end-to-end. A host that advertises `capabilities.secrets.supported: true` MUST resolve the canary `openwop-conformance-canary-secret` via its `SecretResolver` and surface only the SHA-256 hex + byte length on every observable channel (variables, events, debug bundle, logs). The raw value MUST NOT leak per `observability.md` §"Redaction" + `threat-model-secret-leakage.md` §SR-1.
528
539
  - **Topology**: single node `resolve-secret` with `typeId: conformance.secret.echo`, `config.secretId: "openwop-conformance-canary-secret"`. Resolves the canary, hashes it, and writes `{secretSha256, secretLength}` to the run's `variables.resolve-secret`.
529
540
  - **Conformance test driver**:
530
- 1. POST `/v1/runs` with `{workflowId: "openwop-smoke-byok-roundtrip"}`.
541
+ 1. POST `/runs` with `{workflowId: "openwop-smoke-byok-roundtrip"}`.
531
542
  2. Poll until terminal.
532
543
  3. **Assert** terminal status is `completed`.
533
544
  4. **Assert** `variables['resolve-secret'].secretSha256` matches `^[0-9a-f]{64}$`.
@@ -604,7 +615,7 @@ Hosts that don't ship a BYOK SecretResolver MAY return `404` / `422` on the star
604
615
  - **Topology**: 4 sequential `core.channelWrite` nodes targeting channel `events` with `ttlMs: 200`, separated by a `core.delay` of 300ms between writes 3 and 4. The 4th write fires after the TTL window has elapsed.
605
616
  - **Inputs**: none. Each node carries a static `value` in its `config` (`a`, `b`, `c`, `d` respectively).
606
617
  - **Conformance test driver**:
607
- 1. POST `/v1/runs` with `{workflowId: "conformance-channel-ttl"}`.
618
+ 1. POST `/runs` with `{workflowId: "conformance-channel-ttl"}`.
608
619
  2. Poll until terminal.
609
620
  3. **Assert** terminal status is `completed`.
610
621
  4. **Assert** `RunSnapshot.variables.events.length === 1` — the 3 priors aged out at the 4th write.
@@ -621,9 +632,9 @@ Hosts that don't ship a BYOK SecretResolver MAY return `404` / `422` on the star
621
632
  - **Topology**: a single `core.identity` node whose `agent` binding is `{ "agentId": "core.conformance.channel-agent", "channel": "stable" }` (no `version`). The host MUST have an active deployment of `core.conformance.channel-agent` on the `stable` channel.
622
633
  - **Inputs**: none. Trigger `manual`.
623
634
  - **Conformance test driver**:
624
- 1. POST `/v1/runs` with `{workflowId: "conformance-agent-channel-dispatch"}`; poll until terminal.
635
+ 1. POST `/runs` with `{workflowId: "conformance-agent-channel-dispatch"}`; poll until terminal.
625
636
  2. **Assert** the first `agent.invocation.started` carries `resolvedChannel: "stable"` and a concrete non-empty `resolvedAgentVersion` (the recorded fact, RFC 0077).
626
- 3. **Replay** via `POST /v1/runs/{runId}:fork {mode:"replay"}`; **assert** the fork's `agent.invocation.started` re-reads the SAME `resolvedAgentVersion`.
637
+ 3. **Replay** via `POST /runs/{runId}:fork {mode:"replay"}`; **assert** the fork's `agent.invocation.started` re-reads the SAME `resolvedAgentVersion`.
627
638
  4. **(Seam-guarded)** Move the `stable` channel via the deployment seam; **assert** a replay of the original run STILL carries the original pin — never re-resolving the moved channel.
628
639
 
629
640
  ---
@@ -674,7 +685,7 @@ The fixtures reference these typeIds:
674
685
  | `conformance.artifact.emit` | artifact-emit | Opt-in (RFC 0205). Produce one artifact of `config.artifactType` with payload `config.data`; emit `artifact.created` naming it; readable through `getArtifact`. |
675
686
  | `conformance.oauth.use` | credential | Opt-in (RFC 0199). Resolve the credential `config.auth` names for the run's Subject, refreshing host-side; no credential ⇒ a `credential` interrupt (with the facet) or a failed node. Never carries token material on any surface. |
676
687
 
677
- An OpenWOP-compliant server's NodeModule registry MUST include implementations for all six core typeIds before seeding fixtures. The `conformance.requiresMissing` fixture node is opt-in — see the row above.
688
+ A host's NodeModule registry MUST include implementations for all six core typeIds before seeding fixtures. The `conformance.requiresMissing` fixture node is opt-in — see the row above.
678
689
 
679
690
  ---
680
691
 
@@ -771,7 +782,7 @@ A host MUST NOT advertise the fixture unless it advertises `httpClient.safeFetch
771
782
 
772
783
  ## Versioning
773
784
 
774
- Each fixture's JSON has its own `version` field. The OpenWOP v1.0 conformance suite targets fixture version 1.0. Fixture spec breaking changes MUST bump the major; the suite MUST refuse to run against an unrecognized fixture version with a clear error message.
785
+ Each fixture's JSON has its own `version` field. The suite targets fixture version 1.x. Fixture spec breaking changes MUST bump the major; the suite MUST refuse to run against an unrecognized fixture version with a clear error message.
775
786
 
776
787
  ---
777
788
 
@@ -779,26 +790,24 @@ Each fixture's JSON has its own `version` field. The OpenWOP v1.0 conformance su
779
790
 
780
791
  ```text
781
792
  conformance/
782
- fixtures.md — this file
793
+ fixtures.md this file
783
794
  fixtures/
784
- conformance-noop.json
785
- conformance-identity.json
786
- conformance-delay.json
787
- conformance-failure.json
788
- conformance-approval.json
789
- conformance-approval-refine.json
790
- conformance-approval-edit-accept.json
791
- conformance-approval-reject-routed.json
792
- conformance-approval-timeout.json
793
- conformance-approval-timeout-approve.json
794
- conformance-approval-reject-loopback.json
795
- conformance-clarification.json
796
- conformance-multi-node.json
797
- conformance-idempotent.json
798
- conformance-cancellable.json
795
+ *.json workflow fixtures (WorkflowDefinition), seeded by the host
796
+ a2ui-v09/ A2UI v0.9 surface payloads (not seeded)
797
+ connection-packs/ connection-pack manifests
798
+ frontend-plugin-packs/ front-end plugin packs
799
+ interrupt-payloads/ InterruptPayload documents (not seeded)
800
+ node-pack-runtime/ node-pack runtime fixtures
801
+ oauth-providers/ synthetic OAuth provider definitions
802
+ pack-manifests/ pack manifests
803
+ prompt-templates/ prompt templates
804
+ trigger-events/ trigger-event payloads
805
+ upstream/ upstream schemas vendored byte for byte (a2a-v1.0.1/, a2ui-v0.9/)
806
+ wasm-packs/ installable WASM node packs
807
+ wasm-sandbox/ WASM modules for the server-free sandbox probe (not seeded)
799
808
  ```
800
809
 
801
- Each JSON is a valid `WorkflowDefinition` per `../schemas/workflow-definition.schema.json`. Servers MUST treat them as opaque blobs to seed verbatim — do not transform field names or strip fields.
810
+ Each top-level JSON is a valid `WorkflowDefinition` per `../schemas/workflow-definition.schema.json`, checked by `fixtures-valid.test.ts`. Hosts MUST seed them verbatim, as opaque blobs: do not transform field names or strip fields. The sub-directories are described in the sections below.
802
811
 
803
812
  ---
804
813
 
@@ -815,6 +824,45 @@ Pack-manifest fixtures are exercised by the server-free `fixtures-valid.test.ts`
815
824
 
816
825
  ---
817
826
 
827
+ ## Front-end plugin pack fixtures
828
+
829
+ The `fixtures/frontend-plugin-packs/` sub-directory holds front-end plugin packs (RFC 0117, `kind: "frontend-plugin"`) that an operator installs to make the plugin boundary observable (RFC 0238 §D). Their shape is checked server-free by `src/coherence/ui-plugin-fixtures.test.ts`.
830
+
831
+ | Fixture | Plugin | Purpose |
832
+ | --- | --- | --- |
833
+ | `ui-plugin-pack-narrow` | `narrow` | RFC 0238 §D: one plugin declaring only `artifact.read` and no `connectSrc` (entry `ui/narrow.html`). The operator installs it under a key trusted for this pack only, never by default, and creates `ui-plugin-narrow-artifact`, a record whose content references the BYOK canary `openwop-conformance-canary-secret` without resolving it. Drives `v2-ui-plugin-boundary`: the frame's isolation and egress policy, `method_not_allowed` for undeclared methods, and no canary material in any dispatch response. Not advertised in discovery `fixtures`. |
834
+
835
+ ---
836
+
837
+ ## WASM fixture packs
838
+
839
+ The `fixtures/wasm-packs/` sub-directory holds two node packs (`language: "wasm"`) an operator installs to make `node-pack-runtimes.md` §WASM observable. Each is a hand-written WebAssembly text module (`module.wat`) with its built `module.wasm` (`build.mjs`, using `wabt`; no Rust toolchain), exporting the RFC 0008 §B functions. Their shape is checked server-free by `src/coherence/wasm-fixture-packs.test.ts`.
840
+
841
+ | Pack | Node | Purpose |
842
+ | --- | --- | --- |
843
+ | `misbehaving-memory` (`vendor.openwop.misbehaving`) | `vendor.openwop.misbehaving.memory-bomb` | Grows linear memory 64 MiB at a time until the host refuses, then traps. A host advertising `nodePackRuntimes.wasm.maxMemoryBytes` MUST emit `cap.breached` `kind: "wasm-memory"`. Drives `conformance-wasm-pack-memory-cap-breach` and `v2-wasm-memory-cap`. |
844
+ | `misbehaving-abi` (`vendor.openwop.misbehaving-abi`) | `vendor.openwop.misbehaving.abi-bomb` | Reports `openwop_abi_version` 999, which no host lists, so a conforming host refuses it at load. Rejection at load is not yet observable over the protocol (TODO §8), so no v2 leg reads it. |
845
+
846
+ ---
847
+
848
+ ## WASM sandbox probe fixtures
849
+
850
+ The `fixtures/wasm-sandbox/` sub-directory holds small WebAssembly modules, each a hand-written text module (`<name>.wat`) with its built `<name>.wasm`. They are NOT packs and are NOT seeded into a server: the server-free probe in `src/lib/wasm-sandbox-probe.ts` loads them directly to witness the sandbox isolation invariants (RFC 0035 §B; `SECURITY/invariants.yaml` `node-pack-sandbox-*`). Escape attempts and the capability gate are checked by inspecting each module's declared imports before instantiation; the memory bound by instantiating under a capped memory; isolated context by instantiating twice.
851
+
852
+ | Module | Expect | Consumed by |
853
+ | --- | --- | --- |
854
+ | `well-behaved-echo` | runs and returns its input | `sandbox-wasm-isolation.test.ts` |
855
+ | `well-behaved-host-fetch` | callable when `host-fetch` is granted; denied without the grant | `sandbox-wasm-isolation.test.ts` |
856
+ | `misbehaving-fs`, `misbehaving-env`, `misbehaving-network`, `misbehaving-process` | `sandbox_escape_attempt` with the matching escape kind | `sandbox-wasm-isolation.test.ts` |
857
+ | `misbehaving-capability-gate` | `sandbox_capability_denied`, naming the capability | `sandbox-wasm-isolation.test.ts` |
858
+ | `misbehaving-memory` | `sandbox_memory_exceeded` on access past the bound | `sandbox-wasm-isolation.test.ts` |
859
+ | `isolation-global` | no state shared between two instances | `sandbox-wasm-isolation.test.ts` |
860
+ | `misbehaving-timeout` | killed with `sandbox_timeout` by a worker-thread kill timer | `sandbox-wasm-timeout.test.ts` |
861
+
862
+ Both scenarios run at major 1 only and need no host.
863
+
864
+ ---
865
+
818
866
  ## Connection pack fixtures
819
867
 
820
868
  The `fixtures/connection-packs/` sub-directory holds canonical connection-pack manifests (RFC 0095, `kind: "connection"`) used as schema-level proof points (validated server-free against `../schemas/connection-pack-manifest.schema.json`) AND as the install payloads the capability-gated behavioral scenarios POST to the `POST /v1/host/sample/connection-packs/install` seam. They are NOT seeded into a server.
@@ -947,12 +995,18 @@ The `fixtures/a2ui-v09/` sub-directory (suite 2.36.0) holds `ui.a2ui-surface` pa
947
995
 
948
996
  The `fixtures/upstream/a2ui-v0.9/` sub-directory vendors `server_to_client.json`, `catalogs/basic/catalog.json` and `common_types.json` from a2ui.org byte for byte, pinned by SHA-256 (RFC 0209 §References; its `README.md` records the URLs, fetch date and the Apache-2.0 notice). They are read only by the corpus gate.
949
997
 
998
+ ## Upstream A2A v1.0.1 schema source (RFC 0205)
999
+
1000
+ The `fixtures/upstream/a2a-v1.0.1/` sub-directory vendors `a2a.proto` from the A2A repository at tag `v1.0.1`, byte for byte, pinned by SHA-256 (`e195bf96ab630c69797851970203e1b2b6b19528f2e9803b7d904b91a5104016`). A2A publishes no normative JSON Schema of its own, so `schemas/v2/part.schema.json` and `schemas/v2/artifact.schema.json` are transcribed from this file. The corpus gate `src/coherence/a2a-parts-schemas.test.ts` checks the digest and compares each schema's member names with the fields of `message Part` and `message Artifact`, so a transcription slip fails the gate. Its `README.md` records the source URL, fetch date and the Apache-2.0 notice. Do not edit it; moving to a later A2A minor re-vendors the file and re-transcribes both schemas. It is read only by the corpus gate and is not seeded.
1001
+
950
1002
  ---
951
1003
 
952
1004
  ## References
953
1005
 
954
- - `README.md` — conformance suite operator docs
955
- - `../schemas/workflow-definition.schema.json` — every fixture validates against this
956
- - `../rest-endpoints.md` — endpoint contracts the fixtures exercise
957
- - `../interrupt.md` — HITL primitive used by approval + clarification fixtures
958
- - `../idempotency.md` — semantics the idempotent fixture exercises
1006
+ - [`README.md`](./README.md) — running the suite
1007
+ - [`coverage.md`](./coverage.md) — which scenarios consume which fixtures
1008
+ - `../schemas/workflow-definition.schema.json` — every top-level fixture validates against this
1009
+ - [`spec/v2/core/runs.md`](../spec/v2/core/runs.md) — the run operations the fixtures exercise
1010
+ - [`spec/v2/core/interrupt.md`](../spec/v2/core/interrupt.md) — approval, clarification and credential interrupts
1011
+ - [`spec/v2/core/idempotency.md`](../spec/v2/core/idempotency.md) — the semantics the idempotent fixture exercises
1012
+ - [`spec/v2/core/replay.md`](../spec/v2/core/replay.md) — replay and fork, used by the replay fixtures
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@openwop/openwop-conformance",
3
- "version": "2.45.22",
4
- "description": "Production-ready black-box conformance suite for OpenWOP v1.0 compliant servers.",
3
+ "version": "2.45.24",
4
+ "description": "Black-box conformance suite for OpenWOP hosts (v2 current; v1 scenarios retained for the frozen v1 tree).",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git+https://github.com/openwop/openwop.git",
@@ -56,6 +56,6 @@
56
56
  "@openwop/spec-artifacts": "file:../spec-artifacts"
57
57
  },
58
58
  "peerDependencies": {
59
- "@openwop/spec-artifacts": "2.45.22"
59
+ "@openwop/spec-artifacts": "2.45.24"
60
60
  }
61
61
  }