Canonical Object Model Guide¶
The Canonical Object Model (COM) is the serialization-independent representation of a DPCS Pipeline Contract (SPEC Ch 3).
Root type¶
pub struct PipelineContract {
pub dpcs_version: String,
pub id: String,
pub name: Option<String>,
pub version: String,
pub metadata: Option<Metadata>,
pub interface: PipelineInterface,
pub graph: PipelineGraph,
pub steps: Vec<PipelineStep>,
pub contract_references: Vec<ContractReference>,
pub data_flow: Vec<DataFlow>,
pub control_flow: Vec<ControlFlow>,
pub execution: Option<ExecutionRequirements>,
pub scheduling: Vec<SchedulingIntent>,
pub quality_gates: Vec<QualityGate>,
pub failure_semantics: Vec<FailureSemantics>,
pub lineage: Option<PipelineLineage>,
pub compatibility: Option<CompatibilityPolicy>,
pub security: Option<SecurityMetadata>,
pub governance: Option<GovernanceMetadata>,
pub extensions: ExtensionMap,
}
SPEC.md is authoritative. When the specification and this guide differ, follow
the specification.
Serialization independence¶
COM types are the canonical in-memory representation. Serde attributes exist at the wire boundary so YAML and JSON documents deserialize into the same COM values.
Wire→COM remains owned (String / Vec / IndexMap). ROADMAP 0.12 “zero-copy
where practical” means analysis borrows from the owned COM (shared
AnalysisContext), and wire serialization filters reserved extension keys
without cloning the full contract — not lifetime-parameterizing PipelineContract.
Extension fields use ExtensionValue and ExtensionMap from the
dpcs crate (not serde_json::Value).
Conversions to and from JSON-shaped values happen only at parse/serialize time.
Identity model¶
Every addressable COM object possesses a stable identifier within the contract (SPEC Ch 3 §5).
| Type | Purpose |
|---|---|
ObjectId |
Stable identifier newtype (is_present() reports emptiness) |
PipelineIdentity |
Root pipeline identity (id, version, dpcsVersion, name) |
ObjectKind |
Kind of addressable object (step, interface port, …) |
ObjectPath |
Deterministic path (interface.inputs.<id>, steps.<id>, …) |
IdentityCatalog |
Catalog of all addressable objects in a contract |
let contract = PipelineContract::from_yaml_file("pipeline.dpcs.yaml")?;
let identity = contract.identity();
let catalog = contract.identity_catalog();
Pipeline interface¶
Every contract defines exactly one [PipelineInterface] (SPEC Ch 4 §3).
Each [InterfacePort] SHALL possess:
- a stable identifier (
id) - an interface name (
name) - a declared contract reference (
contractRef) - a logical purpose (
purpose)
Ports deserialize with optional fields for ergonomics. COM invariant validation
reports missing properties using canonicalObjectModel diagnostics.
contract.interface.input("customer_raw");
contract.interface.output("customer_clean");
contract.interface.all_ports();
Metadata¶
DPCS names metadata as a root and interface slot. This crate provides an initial
profile on [Metadata]:
descriptionownertags- extension fields
Additional metadata MAY be supplied through extension fields.
Pipeline graph (0.4.0)¶
[PipelineGraph] includes entry/exit points, optional metadata, and directed edges:
pub struct PipelineGraph {
pub entry_points: Vec<String>,
pub exit_points: Vec<String>,
pub metadata: Option<Metadata>,
pub edges: Vec<GraphEdge>,
pub extensions: ExtensionMap,
}
[DataFlow] may declare an associated contractRef. [DependencyGraph] builds a
directed step dependency graph from explicit graph edges, control flow, and
data flow where both endpoints resolve to steps.
use dpcs::DependencyGraph;
let graph = DependencyGraph::from_contract(&contract);
let order = graph.topological_order()?;
Contract references and nesting (0.13.0)¶
[ContractReference] locations are deep-resolved before planning (SPEC Ch 7)
via dpcs::resolve. Nested DPCS documents (type: dpcs / step
dpcs:pipeline) load into PipelinePlan.nested with port lists, step order,
and recursive children. Companion ODCS/DTCS content may remain external.
Prefer ResolveOptions::from_document_path when location is relative to the
contract file. See PLANNING.md and PUBLIC_API.md.
COM validation¶
COM invariants run as the first validation phase after document checks:
- Pipeline identity completeness
- Addressable object identifier presence and uniqueness
- Interface port completeness
- Extension key collision with reserved root fields
Later validation phases (structural, graph, references, flows, execution, scheduling, quality, failure, lineage) build on the COM.
Full validation for the execution model shipped in roadmap 0.6.0. Capability matching against orchestrator profiles shipped in roadmap 0.7.0.
Execution model COM (0.6.0)¶
| Type | Key fields |
|---|---|
ExecutionRequirements |
requiredCapabilities, resources, environment, isolation, externalDependencies |
SchedulingIntent |
required mode; optional cron/frequency/events/constraints |
QualityGate |
id, purpose, criteria, onSuccess, onFailure, optional placement |
FailureSemantics |
id, scope, triggers, responses, optional retry / recovery |
PipelineLineage |
datasets, steps, provenance, optional audit |
Capability profile COM (0.7.0)¶
| Type | Key fields |
|---|---|
CapabilityProfile |
identity (alias profile), dpcsVersion (default empty), capabilities (objects or bare id strings), limitations, optional metadata |
CapabilityDecl |
id, optional category, optional (default false) |
Metadata and registries (0.9.0)¶
| Type | Key fields |
|---|---|
SecurityMetadata |
secretRefs, integrityRefs, optional securityDomain / auditPolicyRef |
GovernanceMetadata |
optional owner, governingAuthority, publicationStatus, publishedAt, tags |
Registry |
id, version, dpcsVersion, owner, artifacts[] |
RegisteredArtifact |
id, type, version, optional compatibility / publication / location |
ExtensionDefinition |
id, namespace, version, owner, scope, optional semantics |
ConformanceProfile |
id, version, dpcsVersion, levels, optional requirements |