# OpenWOP v2 Core — Overview

> Source: https://openwop.dev/spec/v2/core/overview.html · OpenWOP, the open-source protocol for multi-agent workflow orchestration. CC BY 4.0.

> **Status: Stable.**

## Why this exists

`spec/v2/core/` is what a host implements to pass the 2.0.0 floor: reading order, the six axioms, and rules other documents reference.

## Reading order

1. [`overview.md`](https://openwop.dev/spec/v2/core/overview.html) — axioms, §0, §0a, claims, `ext/`
2. [`versioning.md`](https://openwop.dev/spec/v2/core/versioning.html) — `OpenWOP-Version`, version axes
3. [`capabilities.md`](https://openwop.dev/spec/v2/core/capabilities.html) — discovery, profiles
4. [`identity.md`](https://openwop.dev/spec/v2/core/identity.html) — Subject, `SubjectLink`, id grammars
5. [`runs.md`](https://openwop.dev/spec/v2/core/runs.html), [`events.md`](https://openwop.dev/spec/v2/core/events.html), [`errors.md`](https://openwop.dev/spec/v2/core/errors.html), [`headers.md`](https://openwop.dev/spec/v2/core/headers.html) — runs, `configurable`, event `oneOf`, registries, `OpenWOP-*` headers
6. [`interrupt.md`](https://openwop.dev/spec/v2/core/interrupt.html), [`idempotency.md`](https://openwop.dev/spec/v2/core/idempotency.html), [`replay.md`](https://openwop.dev/spec/v2/core/replay.html), [`conversation.md`](https://openwop.dev/spec/v2/core/conversation.html), [`execution.md`](https://openwop.dev/spec/v2/core/execution.html), [`persistence.md`](https://openwop.dev/spec/v2/core/persistence.html)
7. [`security-defaults.md`](https://openwop.dev/spec/v2/core/security-defaults.html), [`webhooks.md`](https://openwop.dev/spec/v2/core/webhooks.html), [`interop.md`](https://openwop.dev/spec/v2/core/interop.html), [`host-services.md`](https://openwop.dev/spec/v2/core/host-services.html), [`storage.md`](https://openwop.dev/spec/v2/core/storage.html), [`tool-catalog.md`](https://openwop.dev/spec/v2/core/tool-catalog.html), [`i18n.md`](https://openwop.dev/spec/v2/core/i18n.html), [`portability.md`](https://openwop.dev/spec/v2/core/portability.html)
8. [`packs.md`](https://openwop.dev/spec/v2/core/packs.html), [`node-pack-runtimes.md`](https://openwop.dev/spec/v2/core/node-pack-runtimes.html), [`connection-packs.md`](https://openwop.dev/spec/v2/core/connection-packs.html), [`form-content-packs.md`](https://openwop.dev/spec/v2/core/form-content-packs.html), [`workflow-chain-packs.md`](https://openwop.dev/spec/v2/core/workflow-chain-packs.html), [`artifact-type-packs.md`](https://openwop.dev/spec/v2/core/artifact-type-packs.html)
9. [`conformance.md`](https://openwop.dev/spec/v2/core/conformance.html) — requirement ids, witness classes, bundles, seams

## Axioms in force

1. A MUST without a witness class is not a requirement.
2. One name per thing. Every alias has a removal date in `spec/v1/deprecations.json` and a codemod id.
3. Closed by default. The discovery root, event envelope, payload and error registries, bundle, and `configurable` are `additionalProperties: false`. Vendor extension is one positive pattern in one namespace.
4. Registers are data. Gaps, risks, deprecations, migrations, witness classes, and dispositions are files with schemas and gates; prose is checked against them, never the reverse.
5. Security defaults are obligations of the surface. A protecting behavior binds when the surface is advertised, never when a flag is set.
6. Nothing persisted under v1 is orphaned. Every v1 artifact has a disposition in the migration register.

## §0 Closed-enum growth rule

A registry-backed enum (event types, error codes, reason vocabularies, lanes) grows by adding a row to its registry and regenerating.

- Consumers MUST accept an unknown member of a registry-backed enum and MUST NOT act on it.
- Producers MUST NOT emit an unregistered member.
- Adding a member is additive in v2.x. Renaming one is a major; removing one is a major except under §0a.

## §0a Retiring a v2 surface

A 2.x minor MUST NOT change the shape of an existing v2 surface; a new shape is a new surface added beside the old one.

A 2.x minor MAY remove a surface only when `scripts/check-v2-retirement.mjs` proves all of the following; otherwise the removal waits for 3.0:

1. Its replacement shipped in an earlier 2.x minor.
2. A `v2-minor` row in `spec/v1/deprecations.json` named the removal minor at least two minors and 30 days earlier.
3. No committed v2 host bundle and no published registry manifest carries it.
4. It is an optional family, facet or enum member, so its absence is already a 2.0 state.
5. Its family is `experimental` in `spec/v2/declaration.json`.
6. No independent host is in the INTEROP-MATRIX v2 table.

Until an outside host exists, a `steward-deletion` row in `spec/v2/corrections.json` can license removing any surface. `check-v2-retirement.mjs` refuses one that misstates its census or removes persisted-data readers, or is new while a tier-3 host is listed.

Readers MUST keep accepting a retired shape on replay, fork and poll; only emission narrows.

## v1 end-of-support

v1 support ends at the later of:

- (a) every INTEROP-MATRIX host's non-vacuous v2 bundle, plus 90 days;
- (b) 18 months from the v2 release — applied if and only if an independent host is in the matrix at release.

The date is computed from the matrix, or set earlier under (c); nothing else MAY set it.

- (c) An `Accepted` RFC MAY set an earlier date once every counted host has a certified non-vacuous v2 bundle in `evidence/v2-host-bundles/` and reports no old-major traffic from third parties (anyone but the host's operator and the conformance suite) over at least the 7 days before the RFC. The date and that evidence are in `spec/v2/eos-override.json`.
- **After the date** a host MAY drop the old major from `protocolVersions[]`; it is not required to that day.
- **The old-major tree** is then frozen as history by a marker naming the date, not edited.
- **Counted hosts.** Those with a row in the INTEROP-MATRIX v2 table.
- **Non-vacuous.** At least one claimed profile carries `witnessCount ≥ 1`.
- **Anchor.** The date the host's signed bundle was committed to `evidence/v2-host-bundles/` in the spec repository, read from the public history (`git log --diff-filter=A`). Never `generatedAt` inside the bundle, which nothing signs. A later re-certification replaces the file and does not move the anchor.
- **The computed date.** `evidence/v1-end-of-support.json`, GENERATED by `scripts/generate-v1-eos-clock.mjs`, which honours a (c) override only when it meets (c). On or after the date, `check-removal-dates.mjs` fails the v1-tree sources of every `v1-end-of-support` row unless that tree is frozen.

### Old-major retention floors

Every published old-major artifact MUST remain installable at its last 1.x version for 12 months from the 2.0.0 publish (the `v2.0.0` tag's commit date). A consumer pinned to the old major MUST be able to rebuild through that window.

The artifacts are the npm packages `@openwop/openwop` (1.x) and `@openwop/openwop-conformance` (1.x), the PyPI package `openwop-client` (1.x), and the Go module `github.com/openwop/openwop-sdks/go` (v1.x). Their identities and last 1.x versions are in `spec/v2/retention-floors.json`. `scripts/check-retention-floors.mjs` prints the floor state and, with `--network`, probes each registry for the pinned version.

Unpublishing, deprecating-with-removal, or retracting a listed version inside the window is a Phase 5 exit failure.

## Profile claim vocabulary

These rules bind any public conformance statement:

- An unqualified "OpenWOP conformant" or "OpenWOP compatible" statement MUST mean `openwop-core-standard`, the executable floor, never the discovery predicate.
- A discovery-only claim MUST say `openwop-discovery-core` and MUST NOT use the same badge as `openwop-core-standard`.
- Every claim MUST state every additional profile it relies on; an omitted profile is an unclaimed one.
- A certification bundle MUST name canonical profile ids; `openwop-core` is deleted (see [`capabilities.md`](https://openwop.dev/spec/v2/core/capabilities.html)).
- A vendor extension MUST NOT use an `openwop-*` id without an accepted RFC.

## What is `ext/`

`spec/v2/core/` stays within the word budget that `scripts/check-core-budget.mjs` enforces; `spec/v2/ext/` holds the rest.

- Every `spec/v2/ext/<key>/` document MUST declare `witness` and both maturity axes (`technical`, `adoption`) in its header.
- A MUST with `witness: unwitnessable` MUST NOT appear in `core/`. A document whose only witness is "deferred to Active → Accepted" enters `ext/` or is deleted.
- An `ext/` family is advertised only under a wire-legal witness class (see [`capabilities.md`](https://openwop.dev/spec/v2/core/capabilities.html)).

## What a MUST means (Axiom 1)

Every MUST, SHOULD, and MAY in `core/` is a requirement with an id in `requirements.json` and a `witness` from `witnessable-unaided | witnessable-gated | seam-gated | claims-check | negative-existence`. A seam-gated MUST is governed by [`conformance.md`](https://openwop.dev/spec/v2/core/conformance.html) §"Witness class".

*Sources: RFCs 0155, 0167, 0168, 0169, 0171, 0174, 0190, 0197.*
