Integration-contract registry¶
The registry stayed; the lock manager left
This note was written while SwarmKit still bundled a pipeline sequencer, so it describes the
StageGraph lock ref-check. The stage graph was removed in runtime 1.189.0
(Extracting the pipeline) and that ref-check went with it. The
registry itself is unchanged and still shipped: contracts resolve into
ResolvedWorkspace.contracts, so the sequencer in your application can check a lock id
against a real artifact. Read the StageGraph passages below as the original motivation.
Scope: schema (new Contract artifact) + runtime (discovery/resolution + StageGraph lock
ref-check) + serve + composer + docs.
Design references: extracting-the-pipeline.md (where the lock manager went) · the retired pipeline-controller note (integration-contract
locking), pipeline-editor-canvas.md (this is its "contract-lock
registry" open question, resolved).
Status: proposed.
Why¶
A pipeline serialises requirements on the integration contracts they share — a stage's
locks: [contract:oms-web, contract:oms-inventory] mean "hold the OMS↔Web and OMS↔Inventory
interfaces while I change them, so no concurrent requirement commits a conflicting version." Today
those lock ids are free-form strings: nothing checks them, a typo (contract:oms-web) silently
becomes a different lock (so two requirements that should serialise don't), the editor can only
offer a free-text chip, and the contention overlay ("which stages fight over the same contract") is
approximate. The contract itself — the agreed interface between two apps — has no home.
Make each integration contract a first-class artifact. Then lock ids are a checked, pickable vocabulary: the resolver rejects a lock that names no contract, the editor offers a picker over real contracts, and contention is exact.
The Contract artifact¶
A contract is the agreed interface between two (or more) applications, identified by id.
apiVersion: swarmkit/v1
kind: Contract
metadata:
id: oms-web
name: OMS ↔ Web order API
description: The order-submission + status API OMS exposes to the Web storefront.
parties: [oms, web] # the apps this contract binds (>= 2)
interface: schemas/oms-web-order.json # optional: where the interface itself lives
provenance:
authored_by: human
version: 1.0.0
parties(required, ≥2) — the apps the contract is between. This is what makes it a contract (an interface between apps), and it drives the editor's contention/ownership display. App ids are free strings (apps are not artifacts).interface(optional) — a pointer to the actual interface spec (an API/event schema). Not interpreted by core; documentation + a handle for reviewers.
What changes in the StageGraph¶
A stage's locks items become contract references:
"locks": {
"type": "array",
"items": { "$ref": "#/$defs/identifier", "x-swarmkit-ref": "contract" }
}
- The resolver ref-checks each lock against the contract registry — an unknown contract is a
stage-graph.unknown-contractresolution error (consistent with howtopology/gaterefs are checked). In this model a lock is an integration contract; the free-string form was the placeholder.release_locks_onis unchanged (it's an event, not a contract). - Migration: the contract ids drop the redundant
contract:prefix — the field islocks, so the id is justoms-web. The OMS example gainscontracts/oms-web.yaml+oms-inventory.yamland its design stage becomeslocks: [oms-web, oms-inventory].
Runtime¶
contractjoins the discoverable artifact kinds (contracts/directory), resolved into aResolvedWorkspace.contractsregistry (id →ResolvedContract), like funnels/roles/stage-graphs.- StageGraph resolution gains the lock ref-check against that registry.
- The contract itself is not executed — the controller/orchestrator is still the lock manager; the
registry only makes the vocabulary real. A contract's
partieslet the manager (and the board) group locks by app-pair.
Composer + serve¶
- Serve CRUD:
/contracts,/api/contracts/{id}(mirrors funnels/pipelines). use-ref-optionsfetches contracts; the StageGraph editor'slocksfield renders as a RefChips picker over workspace contracts (the existingx-swarmkit-refarray machinery — no new UI mechanism), replacing the free-entry chips.- A Contracts artifact surface (list + schema form), like funnels.
- Exact contention overlay: the pipeline canvas highlights stages that hold the same contract
id (now guaranteed to be the same real contract), and can label a contract by its
parties.
Docs / authoring¶
Contract joins the artifact-kind enumerations: llms.txt (a Contract section), a reference page, the
authorable-kinds list, and the knowledge-server write-path (contracts/). The knowledge server
auto-globs schemas, so get_schema("contract") surfaces for free.
Non-goals¶
- Not contract content validation. Core does not parse or diff the
interfacespec — that is the SIT/contract-testing stage's job (a later slice). The registry governs identity + locking, not interface compatibility. - Not app artifacts.
partiesare free strings; apps do not become a kind here. - Not a new lock manager. Locking stays in the orchestrator (reference controller / Temporal adapter); this only makes lock ids checkable and pickable.
Test plan¶
- Schema (Py + TS): a valid contract parses; missing
parties/<2 partiesis rejected; the newcontractschema round-trips its fixtures. - Resolution: contracts discovered into
ResolvedWorkspace.contracts; a StageGraph lock naming a real contract resolves; an unknown lock isstage-graph.unknown-contract; the OMS workspace resolves with its two contracts. - UI:
locksrenders as a contract RefChips picker; the contention overlay groups stages by shared real contract.
Demo plan¶
Extend just demo-pipeline-controller / the pipelines UI: two OMS requirements both locking
oms-web serialise (already demoed) — now the lock is a checked contract, a typo'd lock fails
resolution loudly, and the editor's locks field is a dropdown of the workspace's contracts.