Skip to content

Developing

Contributions to OpenOP are welcome. This guide takes a change from an idea to a merged merge request (MR) while keeping the platform modular, consistent, and maintainable. The short version: do not just make the feature work, make it fit OpenOP.

The guide does not repeat the OpenOP architecture specifications or the module documentation. Those stay the authoritative source for design details.

Before you start

To contribute code, you need to be a Corporate Contributor or an Individual Contributor as described in the Detailed Working Procedures. See Roles for how to become one. The code lives in the OpenOP GitLab group and is publicly accessible.

This guide uses these governance terms:

MDG Leader
The leader of the Module Development Group (MDG) that maintains a module, appointed by the TSC as the Detailed Working Procedures describe. Every change to a module needs its MDG Leader's review.
Technical call
The regular OpenOP technical meeting, where architecture proposals are discussed.
TSC
The Technical Steering Committee. It approves architecture changes. The TSC Chair approves every MR in the architecture repository and may also review cross-cutting or high-impact contributions.

The OpenOP team page lists the MDG Leader of each module. To join the technical call, or if a module has no MDG Leader listed there, contact SDGsupport@etsi.org.

Choose your path

Change Examples Before you code Reviewed by
Small change Bug fix, tests, documentation, small refactor Follow the module's conventions. The MDG Leader
Feature within the existing architecture A capability the architecture already supports Start from an issue, check the specification, and identify the affected modules. Each affected MDG Leader
Architecture change A new capability, responsibility, or cross-module contract Follow When the architecture needs to change. The TSC, then each affected MDG Leader

Most contributions take one of the first two paths. Architecture governance applies only when you change the architecture, not when you implement something the architecture already supports.

Contribution workflow

  1. Start from an issue that describes the requirement. Every non-trivial change has one.
  2. Understand the expected behavior from the issue, the use case, and any external specification the change implements e.g. a CAMARA API.
  3. Read the OpenOP architecture specification and the accepted architecture decisions, and identify the affected modules.
  4. Check whether the change fits the existing OpenOP capabilities, responsibilities, and contracts. If it does not, or if you are unsure, discuss the gap before you build a workaround.
  5. If the change needs a specification change, update the architecture specification it affects and open an MR in the architecture repository before you change code. The MDG Leader of each affected module and the TSC Chair approve it. Otherwise, note in the issue which specification section the change implements.
  6. Fork the module repository, or create a branch if you have developer rights, from develop. Implement the change with the module's existing patterns, add tests, and update the module's own documentation.
  7. Open an MR against develop. Link the architecture MR if there is one: the code MR merges after it, as described in Merge requests and review. Otherwise, reference the specification section it implements.

Fit the platform and the module

Map the requirement into OpenOP before you write code:

  • Which existing OpenOP capability supports it?
  • Which module responsibilities are involved?
  • Which contracts already exist between those modules?
  • Does each affected module already support its part of the flow?

Do not translate an external API directly into implementation code without knowing how it fits the platform.

Inside a module, reuse its structure, patterns, libraries, configuration mechanisms, error handling, persistence model, testing approach, and code-quality tooling. Do not introduce a second way of solving a problem that the module already solves. If the existing approach is not enough, discuss it with the MDG Leader instead of quietly introducing a new pattern.

When the architecture needs to change

A contribution becomes an architecture discussion when it requires, for example:

  • a new OpenOP capability or platform responsibility
  • a new cross-module contract or interaction
  • a significant change in state ownership
  • a significant change in synchronous or asynchronous behavior
  • a new platform-wide mechanism
  • anything else that does not fit the approved architecture

In these cases, agree on the design before substantial implementation begins:

  1. Open or update the issue. Describe the requirement and the gap.
  2. Draft the proposed architecture change. Consider the whole platform: existing capabilities, modules, state, security, failure handling, federation, and future reuse.
  3. Present the proposal in the technical call.
  4. Get TSC approval.
  5. Update the specification.
  6. Implement the change through the contribution workflow.

You are encouraged to propose the solution yourself. The process does not exist to block new ideas. It makes sure that an immediate feature does not take a platform-wide design decision by accident.

If the documented architecture looks wrong, raise an issue. Do not follow it blindly, and do not silently replace it in code either.

Engineering expectations

Apply these principles where they are relevant to your change.

Reuse before you create
Prefer existing OpenOP capabilities, contracts, abstractions, libraries, and platform mechanisms. Add something new only for a clear gap, not because another implementation would be more convenient.
Keep responsibilities clear
Logic belongs in the module responsible for that behavior. Do not bypass module boundaries to make an implementation easier.
Give state one owner
Before you add or copy state, identify the component that is authoritative for it. Do not create a second source of truth without an agreed ownership and synchronization model.
Choose sync or async deliberately
Use synchronous interactions for bounded queries that need an immediate result. Use asynchronous interactions for long-running, lifecycle-changing, retryable, or externally dependent workflows. If the specified interaction does not make sense for the platform, raise it.
Think beyond the happy path
Consider failures, retries, timeouts, duplicate requests, partial completion, and recovery. Use the mechanisms the platform already has instead of feature-specific alternatives.
Keep compatibility
Changes to APIs, events, schemas, configuration, persisted data, deployment assumptions, or internal contracts must stay backward compatible. A breaking change must be identified, documented, and explicitly agreed, never introduced silently.
Use the existing security mechanisms
Do not create a feature-specific authentication, authorization, or trust model when a platform mechanism applies. If your change exposes a missing platform-level capability, document the gap and propose the improvement.
Consider federation
Not every feature has to solve federation, but your design should not prevent or complicate federated operation without need. Record significant federation implications in the issue or the architecture discussion.

Example: adding a CAMARA API

A new CAMARA API is a typical larger contribution. Do not start by adding an endpoint to the exposure layer. Instead:

  1. Read the CAMARA API and list the behavior it requires.
  2. Find the OpenOP capability that provides that behavior. If none does, or if it is unclear, the change is an architecture change.
  3. Identify the module responsibilities and contracts that take part. If a module cannot support its part of the flow, discuss the gap before you implement.
  4. Implement the API and test its conformance with the CAMARA specification.

Think about the complete platform flow, not only the northbound API:

External API
     ↓
Exposure
     ↓
OpenOP capability / platform behavior
     ↓
Technology-specific execution where required
     ↓
Network / compute / external system

The exact modules and interactions depend on the capability and follow the current OpenOP architecture. Check the design against the engineering expectations. The goal is to implement the API through the OpenOP platform model, not to create a feature-specific path through the system.

Testing, code quality, and documentation

Testing is part of the implementation. Follow the module's existing testing patterns and add enough coverage to prove the new or changed behavior. Depending on the change, that means unit, API or contract, module integration, cross-module integration, or end-to-end tests. Not every change needs every level, and you can write the tests before or after the code.

  • Bug fixes include a regression test whenever practical.
  • For standards-based APIs, conformance with the referenced specification is part of the definition of done. Use the existing conformance or contract tests where they exist.
  • Follow the module's formatting, linting, typing, dependency-management, and code-quality tooling.
  • Small refactors that a clean implementation needs are welcome. Put unrelated refactoring or cleanup in a separate MR.

The architecture specification changes before the code, in its own MR, as the contribution workflow describes. Ask the MDG Leader which module, API, configuration, deployment, or developer documentation the change affects, and update it in the code MR.

AI-assisted contributions

You may use AI tools to write code, tests, documentation, or architecture proposals. The same rules apply as for any other contribution:

  • You are responsible for every line you submit. Understand it, test it, and be ready to explain it in review.
  • Say in the MR description which tools you used and for what, for example "tests drafted with an AI assistant".
  • Make sure the output does not reproduce third-party code under a license that is incompatible with Apache 2.0. Your contributor agreement still applies.
  • Do not paste confidential or non-public information into AI tools.
  • AI output does not replace the architecture work. It must fit the specification like any other change.

Reviewers may close issues or MRs that look generated without care, such as unverified code or text that does not match the actual change.

Branches and commits

Branch from develop and target develop. Name the branch after the type of change:

feat/<short-description>
fix/<short-description>
chore/<short-description>
docs/<short-description>
test/<short-description>
refactor/<short-description>

Write commit messages in the Conventional Commits format, with the same types:

feat: add QoD session expiry notification
fix: return 404 for an unknown application instance

Research project and experimental contributions

Research projects sometimes build contributions for a future OpenOP release that cannot be integrated into develop yet. That work can live in branches namespaced by project, which may stay based on an older OpenOP version:

<project-name>/feat/<short-description>
<project-name>/fix/<short-description>

The project also opens an OpenOP issue that describes the contribution, so that its value, architecture fit, and future integration can be reviewed.

Project branches are not part of the accepted OpenOP architecture or implementation baseline. To integrate the work later, evaluate it against the current architecture and take it through the normal contribution workflow. Stale project branches may be removed.

Merge requests and review

Keep each MR to the smallest coherent change that reviewers can understand safely. Link the issue or issues it addresses, and describe:

  • the problem it solves and what changed
  • the affected modules
  • the relevant specification or architecture section
  • how you tested it
  • compatibility and documentation impact
  • the architecture MR
  • anything reviewers should look at closely

Open the MR as a draft while the work is in progress. A draft invites early feedback but is not reviewed for merge. Mark it ready when it meets the definition of done as far as you can check it yourself.

Approval and merge

  • Each affected MDG Leader approves the part of the change in their module. A change that spans several modules is also reviewed end to end as a whole.
  • An MR in the architecture repository needs the approval of each affected MDG Leader and of the TSC Chair. A code MR that links an architecture MR merges only after the architecture MR has merged.
  • Authors do not approve their own MR. When the author is the MDG Leader, another MDG Leader or the TSC Chair approves it.
  • The MDG Leader merges the MR, not the author.
  • MRs are squash-merged into develop. The MR title becomes the commit message, so write it in the Conventional Commits format.
  • Keep the branch up to date by rebasing it on develop, and resolve conflicts before you ask for the final review.
  • CI is a merge gate. Do not bypass a failing pipeline. If a failure comes from infrastructure or a flaky test, the maintainers identify and handle it explicitly.

Review times and inactive MRs

  • If you get no response after five working days, mention the MDG Leader in a comment on the MR. If that does not help, ask on the OOP_TECH mailing list.
  • Reply to review comments, or say when you will get to them. A reviewer marks an MR as stale after 30 days without activity from the author, and closes it 14 days later.
  • You can reopen a closed MR when you resume the work. A maintainer may also take over a stale MR and keep the original author's credit in the commits.

Definition of done

An MR is ready to merge when:

  • It is linked to an issue, and its intended behavior is clear.
  • It fits the approved OpenOP and module architecture, or the required architecture change has been agreed.
  • The relevant tests and conformance checks pass.
  • Compatibility, state, failure, security, and federation implications have been considered where relevant.
  • Any required architecture MR has merged, or the MR references the specification it implements, and the required configuration and documentation changes are included.
  • Each affected MDG Leader has approved it.
  • CI is green.

When something is unclear, raise it early. A discussion before implementation costs much less than maintaining an architectural shortcut once it is part of the platform.