Thanks for your interest in contributing to OpenFoundry. This document is the single source of truth for how to propose changes, what we expect from a pull request, and how reviews and releases work. Read it before opening your first PR — it will save you (and the maintainers) time.
TL;DR
- Open an issue first for anything non-trivial.
- Fork, branch from
main, follow Conventional Commits.- Run
just lint testlocally before pushing.- Keep PRs small (< ~400 lines diff), focused, and with tests.
- Changes touching
libs/core-models,libs/auth-middleware,proto/**or any public SDK require an RFC (see below).
- Code of Conduct
- Ways to contribute
- Project layout
- Development environment
- Workflow
- Branch and commit conventions
- Pull request checklist
- Review process
- Tests and quality gates
- RFCs and breaking changes
- Adding a new service
- Documentation contributions
- Security issues
- Licensing and DCO
- Getting help
Participation in this project is governed by our
Code of Conduct (Contributor Covenant 2.1). By
contributing, you agree to uphold it. Report unacceptable behaviour to
conduct@openfoundry.dev.
You don't need to write Rust to help. We welcome:
- Bug reports — use the bug report template.
- Feature proposals — use the feature request template.
- New service proposals — use the new service template.
- Documentation improvements under
docs/. - SDK examples in
sdks/. - Plugins built on top of
libs/plugin-sdk. - Triage: reproducing bugs, labelling issues, reviewing PRs.
If you are looking for a starting point, filter issues by
good first issue or
help wanted.
OpenFoundry is a Cargo + pnpm + buf monorepo. The pieces you are most likely to touch:
| Path | Purpose |
|---|---|
services/ |
~85 Rust microservices (one crate per service). |
libs/ |
Shared Rust libraries (auth, event bus, plugin SDK, storage, etc.). |
proto/ |
gRPC / Protobuf contracts. Source of truth for inter-service APIs and SDKs. |
apps/web/ |
Frontend (TypeScript, pnpm workspace). |
sdks/ |
Generated SDKs for Python, TypeScript and Java. |
docs/ |
Public documentation site (VitePress). |
infra/ |
Local stack, Helm charts, Terraform, runbooks. |
benchmarks/, smoke/ |
Performance and end-to-end scenarios. |
A more detailed map lives in docs/guide/repository-map.md
and ARCHITECTURE.md.
Required tooling
- Rust 1.85+ (workspace MSRV;
rustup default stable). - Node 20+ and pnpm 9+ (
corepack enable). justtask runner.- Docker / Docker Compose (for the local stack).
buffor protobuf changes.
First-time setup
git clone https://github.com/open-foundry/open-foundry.git
cd open-foundry
just dev-stack # Postgres, Redis, NATS JetStream, MinIO via docker compose
just build # cargo build --workspace
just test # cargo test --workspaceThe full local-development guide lives at
docs/getting-started/local-development.md.
Useful recipes (see justfile for the full list)
just build-svc <crate> # build a single service
just test-svc <crate> # test a single crate
just lint # fmt-check + clippy -D warnings
just deny # cargo-deny (licenses + advisories)
just proto-gen # regenerate code from proto/
just db-migrate # run sqlx migrations for every service- Search existing issues / discussions to avoid duplication.
- Open an issue for any change that is not a typo / docs fix / one-line bugfix. Get rough agreement on the approach before writing code.
- Fork the repository and create a branch from
main:git checkout -b feat/ontology-bulk-import. - Implement the change, adding tests and updating docs.
- Run quality gates locally:
just lint test deny. - Push and open a pull request against
main. - Iterate with reviewers; keep the branch rebased on
main. - A maintainer will squash-merge the PR once approved and CI is green.
We do not accept force-pushes to shared branches and we do not rebase
merge commits in main.
-
Branch names:
<type>/<short-description>(e.g.feat/nexus-bulk-export,fix/auth-jwt-leeway,docs/contributing-guide). -
Commits: Conventional Commits. This is enforced in CI and drives the changelog.
feat(ontology): add bulk import endpoint fix(auth-middleware): tolerate clock skew up to 60s docs(getting-started): document just dev-stack refactor(core-models): split dataset types into own module chore(deps): bump tokio to 1.40Allowed types:
feat,fix,perf,refactor,docs,test,build,ci,chore,revert. A!after the scope (feat(api)!: ...) or aBREAKING CHANGE:footer flags a breaking change.
Every PR must satisfy this checklist before review:
- Linked to an issue (
Closes #123) when applicable. - Diff stays focused; unrelated changes split into separate PRs.
-
just lint testpasses locally. - New / changed behaviour covered by tests (unit, integration, or smoke).
- Public APIs (proto, SDK, REST) updated together with their generated
artefacts (
just proto-gen,just sdk-typescript-gen, etc.). - Docs in
docs/updated when behaviour or interfaces change. - An entry added to the Unreleased section of
CHANGELOG.mdfor any user-visible change. - Migrations are forward-only and reversible scripts are provided
(
cargo sqlx migrate add -r ...). - No secrets, credentials, or customer data committed.
PRs that fail any of the above will be sent back without a review round.
- Routing: GitHub auto-assigns reviewers based on
.github/CODEOWNERS. At least one CODEOWNER approval is required for the touched paths. - SLA: maintainers aim to triage within 3 business days and to give a first review within 7 business days. Ping the PR if you have not heard back after that window.
- Merge strategy: squash-merge with the PR title used as the commit message (must follow Conventional Commits).
- Stale PRs with no contributor activity for 30 days are auto-labelled
staleand closed after 14 more days. Reopen freely when you have time.
CI runs on every PR (see .github/workflows/):
cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningscargo test --workspace(Postgres + Redis services spun up by CI)cargo deny checkbuf lintandbuf breakingagainstmain- OpenAPI drift check and SDK typecheck (TypeScript / Python)
- Frontend lint, typecheck, unit and E2E tests
- Helm and Terraform validation
A PR cannot be merged with red CI. If a check is genuinely flaky, document it in the PR and ping a maintainer; do not disable it.
Coverage — we are progressively introducing per-crate coverage gates with
cargo llvm-cov. New code in a touched crate should not lower its coverage.
Some changes need a written design before implementation:
- Any change to the public API surface (
proto/**, generated SDKs, REST routes documented in OpenAPI). - Any change to
libs/core-modelsorlibs/auth-middlewaretypes re-exported by services. - Introducing a new cross-cutting library under
libs/. - Adding or removing a service under
services/. - Changes to the storage schema that require coordinated migrations across more than one service.
Process:
- Open an issue using the
RFC: <title>prefix and thekind/rfclabel. - Fill the RFC template (context, decision, alternatives, consequences, migration plan).
- Allow 7 days minimum for community comments.
- A maintainer marks the RFC as accepted, rejected, or
needs-revision. Accepted RFCs land as a Markdown file under
docs/adr/and can then be implemented.
Breaking changes to protos must additionally:
- Bump the package version (
open_foundry.<domain>.v1→v2). - Keep the previous version compiling for at least one minor release.
- Be flagged with
!and aBREAKING CHANGE:footer in the commit message.
We try to keep the 85+ services consistent. Before adding a new one:
- Open a
new serviceissue and get approval from a Platform CODEOWNER. - Use
just new-service <name>(when available) or copy an existing, minimal service such asservices/health-check-serviceas a template. - Register the crate in the root
Cargo.tomlworkspace members and in.github/CODEOWNERS. - Add proto definitions under
proto/<domain>/v1/and regenerate. - Add at minimum: a
/healthendpoint, structured tracing viacore_models::observability::init_tracing, sqlx migrations underservices/<name>/migrations/, and a smoke scenario undersmoke/scenarios/.
- The public site lives in
docs/and is built with VitePress. - Preview locally with
pnpm --filter docs dev. - Reference docs for SDKs are generated; edit the source proto / Rust doc-comments, not the generated output.
Do not file security vulnerabilities as public issues. Follow the
disclosure process documented in SECURITY.md.
-
OpenFoundry is licensed under AGPL-3.0-only (see
LICENSE). -
By contributing you agree that your contribution is licensed under the same terms.
-
All commits must be signed off with the Developer Certificate of Origin:
git commit -s -m "feat(scope): your message"CI rejects PRs whose commits are not signed off.
- Documentation: https://diocrafts.github.io/OpenFoundry/
- Discussions / Q&A: GitHub Discussions on this repository.
- Chat: see the Community section of the README.
- Maintainer ping: mention
@open-foundry/maintainerson your issue or PR.
Thanks for helping make OpenFoundry better. 🛠️