Skip to content

Latest commit

 

History

History
102 lines (80 loc) · 4.86 KB

File metadata and controls

102 lines (80 loc) · 4.86 KB

Contributing to MetaObjects

Thanks for your interest! MetaObjects is a cross-language metadata standard with five language ports (TypeScript, C#, Java, Python, Kotlin) kept in lockstep by shared conformance corpora. This guide covers how to propose changes.

Before you start

  • New here and looking for a place to jump in? Browse the good first issue label for low-barrier, well-scoped starting points.
  • This is a primarily one-person, part-time project — issues and PRs are welcome, but expect reviews on the order of days, not hours.
  • For anything non-trivial (new metamodel behavior, a new generator, a cross-language change), open an issue first to discuss the approach. Small, obvious fixes can go straight to a PR.
  • MetaObjects is a public repository. Never include private/other-project names, client names, personal information, or absolute local paths in code, docs, fixtures, or commit messages. Use generic terms ("a downstream consumer", "a sibling project") and repo-relative paths (<repo-root>). A CI leak-scan job and a local pre-commit hook enforce this.

How to contribute a change

  1. Fork the repo and create a branch from main.
  2. Make your change following the discipline below — tests first (TDD).
  3. Run the gates locally with scripts/ci-local.sh (or --quick to skip the docker integration suite) and make sure it's green. This matters: to keep CI costs down, the heavy correctness gates (the cross-port conformance matrix, the full Java reactor, the drift/mutation gates, and the integration-tests testcontainers matrix) no longer run automatically on PRs — they are release gate (v*) + on-demand only. Local CI is now the primary correctness gate.
  4. Open a pull request against main and fill out the PR template.
  5. The public-repo leak-scan gate still runs on every PR; a maintainer runs the full gates (locally or via the on-demand workflow) and approves before merge.

The cardinal rule: the metamodel is the spine

The metamodel vocabulary (types, subtypes, attributes) is identical across all five ports, enforced by the conformance corpora. Adding or changing metamodel behavior means adding/updating a conformance fixture so every port verifies it — see spec/conformance-tests.md and fixtures/conformance/.

  • Never invent a metamodel attribute (ADR-0023). Every accepted attribute must come from a registered provider plus a registry-conformance fixture. If a generator can derive something from existing metadata, derive it — don't add an attribute. See spec/decisions/ADR-0023-strict-metadata-provenance.md.
  • Preserve the cross-language wire format and vocabulary exactly — see CLAUDE.mdCross-language porting.

Coding discipline

  • TDD — write the failing test first, then the implementation.
  • Named constants for metamodel strings — never inline "field", "object", etc. (TS: server/typescript/packages/metadata/src/constants.ts).
  • No any escape hatches (TS) — use unknown and narrow.
  • No backwards-compat hacks.
  • Match the surrounding code's style, naming, and idioms.
  • Read an existing generator/port before adding a new one — the patterns are intentionally consistent.

Running tests

# TypeScript — once, at the repo root:
bun install
cd server/typescript && bun test          # TS server suite (run scoped, never a bare root `bun test`)

cd server/csharp     && dotnet test       # C#
cd server/java       && mvn test          # Java + Kotlin
cd server/python     && pytest            # Python (in its .venv)

Cross-language persistence / api-contract corpora (Docker + Testcontainers) run via scripts/integration-test.sh.

Local CI (run this before opening/merging a PR)

Because the heavy gates no longer auto-run on PRs (cost), reproduce the full CI locally with one command:

scripts/ci-local.sh            # full parity: leak-scan, all-port conformance,
                               # java reactor, drift/mutation gates, + docker
                               # integration suite
scripts/ci-local.sh --quick    # everything except the docker integration suite

It SKIPS (loudly, not silently) any port whose toolchain (bun/dotnet/uv/mvn) isn't installed. The .githooks/pre-push hook additionally runs the TS build+typecheck gate and a Java pom-version drift guard on every push (activate hooks once per clone: git config core.hooksPath .githooks).

Releasing

Maintainers only — see docs/RELEASING.md.

License

By contributing, you agree your contributions are licensed under the project's Apache License 2.0.