Conveyor CI Client SDKs/Libraries Software Design Document. This document serves as a reference for implementing Client SDK libraries for Conveyor CI.
This Software Design Document (SDD) defines the architecture of the Conveyor CI Driver Runtime. It serves as a reference for developers and engineers who would like to implement, manatain and contribute to a languange specific runtime by describing how the runtime works, how its cmponents interact with each other and the COnveyor CI system and the desgin decisions behind it. This document is primarily intended for developers building or maintaining Conveyor CI Driver SDKs across different programming languages.
The Conveyor CI Driver Runtime is a runtime architecture used to execute Conveyor CI Drivers that provides a shared standard protocal and utilities such as event handling, logging, scaling, and API communication, allowing driver authors to focus on domain-specific logic. This SDD focuses on that runtime layer, not individual driver implementations or the Conveyor CI API Server itself.
In scope
Out of scope
| Term | Definition |
|---|---|
| CI | Continuous Integration |
| Driver | A program that reacts to Conveyor CI events and reconciles resources |
| Runtime | Execution environment that hosts and manages drivers |
| JetStream | NATS persistence and streaming subsystem |
Reconcile | Driver-defined function invoked per event |
| Stakeholder | Concerns |
|---|---|
| Driver Developers | Ease of use, stable APIs, observability |
| Runtime Maintainers | Modularity, testability, scalability |
| Platform Operators | Reliability, performance, fault isolation |
| Ecosystem Contributors | Language portability, clear abstractions |
The following viewpoints are used to describe the system:
Viewpoint: Context The Driver Runtime operates as an execution environment between Conveyor CI infrastructure (API Server and NATS Server) and user-defined Drivers.
External Actors
Responsibility
Reconcile function eachtime an event is recieved.Viewpoint: Composition
The runtime is composed of the following primary components:
Each component is designed to be replaceable and portable across languages.
The logical architecture defines the core abstractions that must be implemented in every language-specific SDK. This structure ensures that regardless of the language, the Driver author interacts with the system through a consistent set of interfaces.
| Component | Role | Primary Responsibilities | Lifecycle / Scope |
|---|---|---|---|
| Driver Manager | Orchestrator | Manages NATS/JetStream connections; creates consumers; executes the "Try-Catch-Ack" loop. | Global (Runtime duration) |
| Driver | User Logic | Defines resource filters; implements the domain-specific Reconcile logic. | Global (User-defined) |
| Driver Logger | Contextual Logger | Enforces structured logging; automatically attaches run_id, driver_name, and timestamp. | Per-Event (run_id scoped) |
| Client | A stateless HTTP client | Provides typed methods for REST API interaction (Secrets, Status updates, Metadata). | Standalone / Reusable |
Viewpoint: How compenents interact with each other.
Typical Flow
messages stream. Depending on the drivers name and resources the driver specified, it filters to listem for events sent on the following subjects:
resources.{{resource}}: with {{resource}} being a place holder for the resource name the driver defines to listen to.drivers.{{driver_name}}.resources.{{resource}}: with {{driver_name}} and {{resource}} being placeholders for the drivers name and the resource name the driver defines to listen to respectively.AckExplicitPolicy and DeliverPolicy should be set to DeliverAllPolicyReconcile function as a parameter. It has default set labels that will be appended t each log message and these include:
run_id: Which is a UUID string that can be accessed by from the event dataReconcile() invoked with paramenters, Reconcile(message.Payload, message.Event, message.RunID, logger) is message is considered as the event data recieved.log() method that allows the driver to send logs that are to be persisited by conveyor CI, this method takes in the log message and any other custom labels that would like to be attached to the log message.logs.{{RUN ID}} subject using JetStream and also send a core NATs Pub/Sub message live.logs.{{RUN ID}}.{{DRIVER_NAME}} subject using NATs. Before sending this data it should encode it to JSON aligining with the Log Entry schema.pipelines.driver.result subject as a Driver Result EventBoth happy-path and failure-path executions are handled asynchronously.
Viewpoint: Information
Below are Primary data structures schemas, they are all encoded to json before being transmitted within Conveyor CI
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Resource",
"type": "object",
"required": ["id", "name", "resource", "metadata", "spec"],
"properties": {
"id": {
"type": "string",
"minLength": 1
},
"name": {
"type": "string",
"minLength": 1
},
"pipeline": {
"type": "string",
"minLength": 1
},
"resource": {
"type": "string",
"minLength": 1,
"description": "Resource type identifier"
},
"metadata": {
"type": "object",
"description": "Arbitrary metadata",
"additionalProperties": true
},
"spec": {
"description": "Resource-specific specification",
"type": ["object", "array", "string", "number", "boolean", "null"]
}
},
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "DriverMessage",
"type": "object",
"required": ["event", "payload", "id", "run_id"],
"properties": {
"event": {
"type": "string",
"minLength": 1,
"description": "Event name, e.g. create, update, delete"
},
"payload": {
"$ref": "resource.schema"
},
"id": {
"type": "string",
"minLength": 1,
"description": "Message ID"
},
"run_id": {
"type": "string",
"format": "uuid",
"description": "Run identifier (UUID)"
}
},
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/driver-result.schema.json",
"title": "DriverResult",
"type": "object",
"required": ["success", "message", "data"],
"properties": {
"success": {
"type": "boolean",
"description": "Indicates whether the operation succeeded"
},
"message": {
"type": "string",
"description": "Human-readable result message"
},
"data": {
"description": "Arbitrary result data",
"type": ["object", "array", "string", "number", "boolean", "null"]
}
},
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "DriverResultEvent",
"type": "object",
"required": ["success", "message", "data", "driver"],
"properties": {
"success": {
"type": "boolean",
"description": "Indicates whether the driver operation succeeded"
},
"message": {
"type": "string",
"description": "Human-readable result message"
},
"data": {
"description": "Arbitrary driver result data",
"type": ["object", "array", "string", "number", "boolean", "null"]
},
"driver": {
"type": "string",
"minLength": 1,
"description": "Driver identifier or name"
}
},
"additionalProperties": false
}{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/log.schema.json",
"title": "Log",
"type": "object",
"required": ["runid", "driver", "timestamp", "message"],
"properties": {
"runid": {
"type": "string",
"format": "uuid",
"description": "Run identifier"
},
"driver": {
"type": "string",
"minLength": 1,
"description": "Driver name"
},
"pipeline": {
"type": "string",
"minLength": 1,
"description": "Pipeline identifier"
},
"timestamp": {
"type": "string",
"format": "date-time",
"description": "RFC 3339 timestamp"
},
"message": {
"type": "string",
"description": "Log message"
}
},
"additionalProperties": false
}Persistence:
Viewpoint: Concurrency
The driver runtime is designed to ensure that multiple driver instances can process events concurrently, this ensures that Horizontal scaling can achieved by running multiple runtime instances. To acheive this, utilize JetStream consumer groups to provide coordination and ordering guarantees. The cosumers should be Durable Pull Consumers with a shared which is the Driver's name
Viewpoint: Deployment
Typical deployment includes:
Context: Drivers must react to system changes in real time.
Options: Polling, Webhooks, Event Streaming
Outcome: Event Streaming via NATS JetStream
Rationale: Low latency, replayability, horizontal scalability.
Context: Multiple SDKs required across languages.
Options: One reference implementation, shared protocol
Outcome: Shared conceptual runtime with language-specific SDKs
Rationale: Maximizes ecosystem reach while keeping consistency.
This SDD describes the conceptual architecture. Language-specific SDKs may adapt structure to fit idiomatic language patterns while preserving these responsibilities and interactions.
This document is intended as architectural inspiration and may evolve alongside Conveyor CI.