Skip to content

Contributing

We are glad to hear you want to help! This document is the definitive guide to branching, commits, reviews, and the Architecture Decision Record (ADR) process. If a section here conflicts with a merge-request template, the template is wrong, please fix it.

Canonical repository: https://gitlab.com/vortexaq/nexus is the single source of truth. All merge requests, reviews, CODEOWNERS enforcement, and releases happen there. Repositories on other hosts are read-only mirrors; pull/merge requests opened against mirrors are not reviewed — resubmit on gitlab.com.

  1. Every non-trivial Merge Request (MR) references the authoritative work specification for the change (issue, design note, or other agreed artifact). If reviewers cannot find the spec from the Merge Request description, the Merge Request is not ready.
  2. Every Merge Request that makes an architectural decision either cites an Architecture Decision Record (ADR) in Overview | docs/decisions/ or adds a new one in the same Merge Request.
  3. No Merge Request expands scope beyond what its specification says. If you need more scope, update the spec first or split a follow-up Merge Request.
  4. The offline checks (just checks) must pass locally before you request review; the live-gateway suites are additionally required when your change touches the request path (see “Merge requests” below).
  5. Install the local pre-commit hooks before your first commit so secrets and format drift are caught before review.

Trunk-based. The default branch is main, always releasable.

  • Short-lived feature branches named <type>/<short-slug> where <type> is one of feat, fix, docs, chore, refactor, test, perf, ci, build.
  • Branches live ≤ 3 working days. Longer-running efforts live on a tracking branch with a clear owner and a burn-down in the Merge Request description.
  • No long-running develop / release branches. Releases are tags on main.
  • Force-pushing to main is forbidden. Force-pushing to your own feature branch is allowed until you request review.

We use Conventional Commits. The subject line is machine-readable and drives release notes.

Format:

<type>(<scope>): <subject>
<body>
<footer>
  • <type> — one of feat, fix, perf, refactor, docs, test, build, ci, chore, revert.
  • <scope> — the service, crate, or area: gateway, control-plane, auth, policy, ingest, trace-ingest, audit, query, console, cli, proto, docs, ci, shared-crate:<name>.
  • <subject> — imperative mood, no trailing period, ≤ 72 chars.
  • <body> — why, not what. Wrap at 100 chars.
  • <footer>BREAKING CHANGE: ..., Closes #123, See-also: docs/decisions/0007-*.md.

Install the repository hooks from the Nexus root:

Terminal window
pre-commit install

The hooks are intentionally fast and fail early. They cover staged secret scanning, formatting checks for changed files, whitespace/end-of-file hygiene, merge-conflict markers, and large-file guards. Passing hooks is not a substitute for CI; it is the quickest way to catch problems before they enter a branch. The full CI reference and local reproduction commands are in CI/CD Pipeline.

  • Title follows the same format as the commit subject.
  • Description includes:
    • Specification: link or pointer to the issue / design note / other artifact that defines the change.
    • ADRs (Architecture Decision Records): list of ADRs this Merge Request assumes, cites, or introduces.
    • Acceptance: bullet list of behaviours this Merge Request implements (each must be verifiable in the tree after merge).
    • Out of scope: anything a reviewer might expect but should not see here.
    • Test plan: commands to reproduce the integration test and unit tests.
  • Before requesting review, run the checks locally. They split into two tiers:
    • Offline — required for every Merge Request (no running stack, no provider keys, no API spend): just checks, which runs fmt-check, lint (clippy), test-workspace, licenses, and the doc-lint script (scripts/check-adr-references.sh). CI also runs the security gates and focused workspace checks described in CI/CD Pipeline.
    • Live — required when your change touches the gateway request path, providers, routing, streaming, or analytics (needs just dev running and real provider keys; consumes API credits): just test (behavior suite) and, for edge/protocol changes, just test-compat / just test-gateway-cert.
  • Draft Merge Requests are welcome for early feedback. Mark as Ready for Review only when the description above is complete.
Path Minimum reviewers
crates/nexus-*, services/* (non-security) 1 reviewer from the owning area
vortex-common-crates/vortex-* (shared across Vortex products) 1 nexus reviewer + 1 shared-crate maintainer
Anything under services/gateway, services/auth, services/policy, services/audit, or any crypto, tls, classification, redaction, escrow subtree 2 reviewers including a security reviewer
docs/decisions/* 2 reviewers including the owners of every service affected by the decision
vortex-common-crates/contracts/* 1 nexus reviewer + 1 shared-crate maintainer

Security-sensitive paths declare their required reviewers in CODEOWNERS. When branch protection requires Code Owner review, bypassing those reviewers requires documented written approval from the security reviewer in the Merge Request.

See ADR 0000 - Recording architectural decisions as ADRs for the canonical procedure. In short:

  1. Open a Merge Request that adds a new ADR in Proposed state.
  2. Include the next unused number (check Overview | docs/decisions/ and ADR Backlog).
  3. Required reviewers = owners of affected services + a security reviewer when the decision touches crypto, classification, audit, or policy.
  4. Merge flips status to Accepted (or Rejected with a short rationale; a rejected ADR is still merged — we keep the record).
  5. A later decision that changes course adds a new ADR and flips the earlier one to Superseded by ADR-NNNN.

Adding a new integration (provider, SDK, telemetry sink, etc.)

Section titled “Adding a new integration (provider, SDK, telemetry sink, etc.)”
  1. Open an ADR capturing why this integration is needed and what it displaces (if anything).
  2. Add the wire contract to Wire Contracts.
  3. If the integration is user-facing, update the user glossary at Glossary.
  4. Ensure the license for any new dependency is on the allowlist in License Policy. If not, that is its own ADR first.
  5. Add at least one integration test that exercises the new surface end-to-end.
  • Versions are tags on main: v0.y.z. Minor bumps (y) are breaking while we are at 0.y; patch bumps (z) are non-breaking.
  • vortex-* shared crates are versioned in lockstep across the workspace.
  • Release notes are generated from the Conventional Commits log; feat: and fix: entries with non-empty <scope> are grouped by scope.

By contributing you certify the Developer Certificate of Origin: you wrote the change or have the right to submit it under the project’s Apache 2.0 license. Sign off every commit:

git commit -s -m "feat(gateway): ..."

This appends a Signed-off-by: Your Name <you@example.com> trailer. Contributions without a sign-off are not eligible for merge or bounty payout.

You must also disclose AI tool use in the Merge Request template and abide by the Code of Conduct.

Bounty claims are governed by Bounty Governance: trust tiers, identity vetting proportionate to risk, named maintainer owners on sensitive paths, mandatory AI-use disclosure, a demonstrated-understanding requirement, and a claim → review → payout lifecycle. “Passes CI” is necessary but never sufficient — merge requires a maintainer who understands and vouches for the change.

Do not open a public issue for a suspected security vulnerability. Follow the private disclosure procedure in Security Policy.