OpenWOP openwop.dev

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 — axioms, §0, §0a, claims, ext/
  2. versioning.md — OpenWOP-Version, version axes
  3. capabilities.md — discovery, profiles
  4. identity.md — Subject, SubjectLink, id grammars
  5. runs.md, events.md, errors.md, headers.md — runs, configurable, event oneOf, registries, OpenWOP-* headers
  6. interrupt.md, idempotency.md, replay.md, conversation.md, execution.md, persistence.md
  7. security-defaults.md, webhooks.md, interop.md, host-services.md, storage.md, tool-catalog.md, i18n.md, portability.md
  8. packs.md, node-pack-runtimes.md, connection-packs.md, form-content-packs.md, workflow-chain-packs.md, artifact-type-packs.md
  9. conformance.md — 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).
  • 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).

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 §"Witness class".

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

Next in Core.

Edit this page on GitHub ↗

  • Versioning and ReleaseHow a v2 host selects a major, what each version axis means, and what a release is.
  • Discovery and CapabilitiesA host advertises what it supports in one discovery document: one record type per family…
  • IdentityWho owns a run, how each lane binds and revokes, and the grammar of links, ids and…
  • RunsCreating, reading, streaming, cancelling, pausing, forking and diffing a run. Every host…