spec icon indicating copy to clipboard operation
spec copied to clipboard

CDEvents Namespacing Proposal (WSDL-Inspired)

Open darckorner opened this issue 8 months ago • 6 comments

CDEvents Namespacing Proposal (WSDL-Inspired)

Purpose

Propose a standardized, extensible namespacing convention for CDEvents to support:

  • Organizational and vendor-defined events
  • Experimental schemas
  • Clear schema versioning
  • Collision-free graph traversal in a SDLC workflow orchestrator or similar system
  • Smooth consumption via DSLs and typed libraries
  • Explicit schema validation via schemaUri

Background

As CDEvents adoption grows, contributors and implementers face the need to:

  • Extend existing events for domain- or org-specific use cases
  • Define new events without a central coordination delay
  • Maintain semantic interoperability across toolchains
  • Validate events consistently in code and DSLs

This proposal draws from WSDL’s targetNamespace model and extends it with structured event typing, schema binding, and semantic versioning.


Event Type Format

We define a structured event type format as follows:

<namespace>.<subject>.<predicate>.<version>
Component Description
namespace Owning org or domain (e.g., dev.cdevents, org.jpmc, com.harness)
subject The entity or process the event describes (e.g., pipelineRun, branch, testCaseRun)
predicate The state change or intent (e.g., started, finished, initialCommit)
version The semantic version of the event schema (e.g., v0.1.0, v1.0.0)

Each fully qualified event type (e.g. dev.cdevents.pipelineRun.started.v0.4.1) should be paired with a schemaUri field in the event’s context, pointing to a schema that validates the full structure of the event.


Examples

Use Case Event Type
Official CDEvents dev.cdevents.pipelineRun.started.v0.4.1
Experimental SIG dev.cdeventsx.cdf-branch.initialCommit.v0.1.0
Vendor-specific com.harness.artifact.approvalGranted.v1.2.0
Org-internal org.jpmc.secops.scanner.failed.v0.3.1

Semantic Versioning Rules

Semantic Versioning governs the schema of the event, not the CDEvents spec as a whole. It enables the independent evolution of event types.

Version Change Definition Examples Compatibility Requirement
MAJOR Breaking change to the event’s schema or field types Removing required fields, changing types ❌ Incompatible with consumers expecting previous version
MINOR Additive changes (e.g., new optional fields) Adding optional customData keys ✅ Backward compatible
PATCH Metadata clarifications or documentation fixes Updating field descriptions ✅ Safe upgrade

Each namespaced event type must include a schemaUri that matches its declared version and structure. This schema:

  • MUST be a superset of the base event’s schema
  • MUST validate any namespaced customData extensions

Base Event Contract Model

All CDEvents (standard, vendor, org-defined, or experimental) must declare a baseEvent in the context section. This creates a clear inheritance tree and enforces semantic interoperability.

Base Event Requirements

  • Inheriting events must:
    • Preserve all required fields from the base schema
    • Not alter types or semantics
    • Add fields only
  • A schemaUri must be provided for each versioned event

Understanding the Roles

schemaUri: This field points to the JSON Schema that defines the event's structure. It enables consumers to validate the event and generate code bindings.

baseEvent: This field indicates the event type from which the current event inherits. It serves as a semantic reference, allowing consumers to understand the event's lineage and apply appropriate processing logic.

Example Metadata Snippet

"context": {
  "type": "com.somecompany.change.created.v0.1.0",
  "baseEvent": "dev.cdevents.change.created.v0.4.1",
  "schemaURI": "https://somecompany.com/cdevents/V1/ci/change/created",
  "version": "0.1.0"
}

Empty Base Event

A new root-level "empty" base event is introduced for net-new event types that do not extend an existing CDEvent. These must align structurally with the CDEvents envelope.

JSON Envelope

{
  "context": {
    "type": "dev.cdevents.base.empty.v0.1.0",
    "version": "0.4.1",
    "id": "<uuid>",
    "source": "<source-uri>",
    "timestamp": "<timestamp>"
  },
  "subject": {},
  "customData": {}
}

Namespaced Plugin Routing via customData

CDEvents may include customData keys using the reserved ns: prefix to denote plugin-specific logic:

"customData": {
  "ns:jenkins": {
    "jobName": "build-api",
    "buildNumber": 5432
  },
  "ns:homedepot": {
    "complianceZone": "blue"
  }
}
  • Conduit (SDLC Workflow Orchestrator) uses these keys to route payloads to registered plugins.
  • Plugins are version-controlled and resolved by name+version from segment definitions.
  • Each plugin SHOULD publish a schema under a known URI and conform to that shape.

Plugin Declaration in Segment YAML

segment: build
plugins:
  - name: jenkins
    version: 1.3.2
  - name: homedepot
    version: 2025.04

At runtime, Conduit looks up plugin versions from its internal registry and applies them to interpret and validate any ns: extensions in customData.


Developer Consumption Model

Schemas linked via schemaUri support:

  • Runtime validation
  • SDK generation
  • DSL autocomplete
  • Policy enforcement
  • Trust and contract stability

Acknowledgements

Inspired by:

  • WSDL targetNamespace
  • Kubernetes Group-Version-Resource (GVR)
  • XSD schema compatibility principles
  • Practical implementations in the Conduit project
  • Collaborative design by Dadisi Sanyika and Benjamin Powell

darckorner avatar Apr 30 '25 05:04 darckorner

I find this proposal interesting. There is something in this direction already through the schemaUri field, but this takes the idea a major step further. I don't have any strong opinions against this proposal. On the contrary it sounds interesting to get a well-defined structure also for experimental & vendor-specific events. The continued existence of the schemaUri field should be considered as part of this proposal as well. It might still serve a purpose, to easily identify the schema used.

Due to my lack of knowledge on the Conduit system/project, could you elaborate a bit more on that? Example?

e-backmark-ericsson avatar Apr 30 '25 06:04 e-backmark-ericsson

Thank you, @e-backmark-ericsson! Great call out. I have updated the issue utilizing schemaURI.

darckorner avatar May 01 '25 00:05 darckorner

Note that the schemaUri is currently optional, and if omitted it is assumed that a producer/consumer of CDEvents knows where to find the official schemas. Most users of CDEvents will probably use the existing SDKs that have built-in support for the schemas, as they are generated from them. And this proposed change might be somewhat hidden from the users of these SDKs, since it could be handled as part of the SDK itself and doesn't need to be exposed to the user unless they want to customize the events.

In your proposal you now propose the schemaUri to become mandatory, which might be fine even though I believe it could still be implicit if no customization is made to the event type, to not pollute the events with redundant information. If making it mandatory the docs must be updated and also all example events and the schemas themselves, to change the schemaUri field to mandatory.

e-backmark-ericsson avatar May 02 '25 07:05 e-backmark-ericsson

Thanks @darckorner for this thorough proposal.

In general, I'm in favour of a more clearly defined namespacing. I like the idea of namespacing custom data, as it enables better use of plugins and possibly collecting custom data from various tools in one event.

I also like the idea of the baseEvent, which allows customising existing events while still enforcing the original event schema.

I have a few questions related to the various sections.

Event Type Format

  • dev.cdeventsx: Anyone can use this today for custom events, with the namespace included in the subject in the form <org>-<subject> to avoid conflicts. What do you envision the dev.cdeventsx role to be if we introduce the proposed root <namespace>? Will open-source projects use their domain for custom events or dev.cdeventsx?

  • vendor-specific vs. org internal: it's not clear to me if these are just examples of if there is a structural difference between these two

Semantic Versioning Rules

Today, we have two versions:

  • the spec version, which is sent in the CDEvents context through a dedicated field
  • the event version, which is part of the event type dev.cdevents.<subject>.<predicate>.<version>

Both versions use semantic versioning rules today. I don't understand what the change proposed here is. Note that @xibz and @davidB are planning a versioning rework, so changes here should be synced.

Empty Base Event

I don't fully understand the need for the empty base event. Custom events have a base schema today, which defines common structures for all custom events. I like the proposed possibility of specifying a baseEvent, but I don't see the need to make it mandatory, which leads to the need for an empty base event. If no baseEvent is specified, only the existing base schema applies. If a baseEvent is specified, the schema of the base event must also be considered when validating. In any case, this looks to me like an implementation detail, and definitely not a show-stopper.

afrittoli avatar May 02 '25 10:05 afrittoli

Thanks for the details

  1. I don't understand, does the schema define the content of customData or subject (or both)?
  2. In "Namespaced Plugin Routing", does it mean that the event's producer knows the consumers/routers?

DISCLAIMER

I'm in favor of:

  • A non-proliferation of custom/org events, as the goal is to create a common language and NOT to replace (IHMO) the existing language/events provided by tools (with complete control of the content by producer, often with more information and existing ecosystem).
  • Extension (by producer,...) should be possible,
  • Easier & faster update of the specs (and implementation)

Data binding and automatic SDK generation are pains to implement from multiple schemas (the case with one schema per predicate), and it could be worse if developers have to support runtime schema changes.

davidB avatar May 05 '25 14:05 davidB

If the schema is "just" for the customData part, and as

  • Stacking schema is not a standard way (=> not supported by SDK generator, json validators,...)
  • Triggering a json validator using schemaUri already requires custom code

Why not define the namespaces in a dedicated field (like customDataContentType), eg.

{
...
"customData": {
  "ns1": {
    ...
  }
},
"customDataNamespace": {
  "ns1": "https://somecompany.com/cdevents/V1/ci/change/created",
}

Alternatively, customData could become an array + use a tag field to identify the structure. The array avoids naming collision on the key; it could be harder to manage (override, duplicate, ...), depending on the use cases.

{
...
"customData": [
  {
    "schemaUri": "https://somecompany.com/cdevents/V1/ci/change/created",
    ...
  }
],

davidB avatar May 05 '25 17:05 davidB