Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ conformance corpora. This guide covers how to propose changes.
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.
- Want to maintain a port or an area? [GOVERNANCE.md](GOVERNANCE.md) sets out the roles,
how merge and publish rights are earned, and how decisions are made.
[MAINTAINERS.md](MAINTAINERS.md) lists who maintains what today; every port is open.
- 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.
Expand All @@ -30,7 +33,9 @@ conformance corpora. This guide covers how to propose changes.
release tags, so your local run is the only check of the rest before merge — see the
*Local CI* section below.
4. Open a **pull request** against `main` and fill out the PR template.
5. A maintainer reviews the change and the checks on the pull request before merge.
5. A maintainer reviews the change and the checks on the pull request before merge. Who can
approve what, and which changes need a core maintainer, is in
[GOVERNANCE.md](GOVERNANCE.md#how-decisions-are-made).

## The cardinal rule: the metamodel is the spine

Expand Down
190 changes: 190 additions & 0 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# Governance

This file says who can do what in the MetaObjects project, how someone earns more rights, and
how decisions are made. [MAINTAINERS.md](MAINTAINERS.md) lists who holds each role today.

MetaObjects is primarily a one-person, part-time project. Today the creator, Doug Mealing, is the
only maintainer. These rules are written down now so that a second maintainer knows the terms
before putting in time.

## Roles

There are three roles.

| Role | Who | What they can do |
|---|---|---|
| Contributor | Anyone who opens an issue, a pull request, a review or a discussion | Propose changes. Review any pull request. Their reviews count toward earning a maintainer role |
| Port maintainer | Someone who owns one area: a language port, the web client, the docs, a generator family or a library (the areas are listed in [MAINTAINERS.md](MAINTAINERS.md)) | Review and merge pull requests that stay inside their area. Triage and label its issues. Publish that area's registry packages once publish rights are granted (see below) |
| Core maintainer | Someone responsible for the project as a whole | Everything a port maintainer can do, in every area. Approve changes to the model format, ADRs and releases. Grant and remove roles |

A person can maintain more than one area. Core maintainers can merge in any area, but should
leave a pull request to the area's port maintainer when there is one.

## How rights are earned

### Becoming a port maintainer

The usual bar is:

- at least 5 merged pull requests in the area, and
- about 2 months of reviewing other people's pull requests in that area.

Anyone can propose a person, including themselves, by opening an issue that links the merged
pull requests and reviews. A core maintainer then decides, using the decision process below.
The bar is a guide. A core maintainer can accept someone earlier when their work makes the case,
and should say why on the issue.

When the role is granted, the person is added to [MAINTAINERS.md](MAINTAINERS.md) and given write
access to the repository. Branch protection still applies to them like everyone else.

### Publish rights

Each port publishes to its own registry: npm for TypeScript and the web client, Maven Central
for Java and Kotlin, NuGet for C#, PyPI for Python. Publish rights are granted separately from
merge rights, because a published version cannot be taken back.

A port maintainer is added as an owner of their port's registry packages when:

- they have been a port maintainer for at least one release of that port,
- their registry account has two-factor authentication turned on, and
- they have walked through [docs/RELEASING.md](docs/RELEASING.md) for that registry with a core
maintainer.

Publish rights cover the packages of that port only. A port maintainer publishes as part of a
release the core maintainers have approved (see "Releases" below). The registry owners for each
package are listed in [MAINTAINERS.md](MAINTAINERS.md), and that list is updated in the same
change that grants or removes access.

### Becoming a core maintainer

A port maintainer can become a core maintainer after at least 6 months in that role, by
invitation from the existing core maintainers. All existing core maintainers must agree.

## How decisions are made

### Lazy consensus

Most decisions are made by lazy consensus. A proposal is made in public, as an issue, a pull
request or a discussion. If no maintainer of the affected area objects within the waiting period,
it is accepted.

- A pull request inside one area can merge once a maintainer of that area approves it and the
required checks pass. There is no fixed waiting period for these.
- A change that touches more than one area waits at least 3 days after it is ready for review,
so the maintainers of each area can look at it.
- A maintainer does not approve their own pull request. Another maintainer of the area, or a
core maintainer, reviews it. While the project has a single maintainer, that maintainer merges
their own changes; this rule applies to an area once it has a second maintainer.
- An objection must give a reason and, where possible, say what would resolve it. An objection
without a reason does not block.

If the people involved cannot agree, the core maintainers decide by majority. If the core
maintainers are split evenly, the creator breaks the tie only on the model format, ADRs and
releases (see below). On any other subject, an even split leaves the proposal unaccepted and the
status quo stands.

### Changes that need a core maintainer

These changes need explicit approval from a core maintainer, even when they sit inside one
area:

- **The model format.** Metamodel types, subtypes and attributes; the canonical serialized form;
`expected-registry.json` and `metamodelVersion`; and the shared conformance corpora under
[`fixtures/`](fixtures/). These are the contract every port has to match.
- **ADRs.** A new or amended decision record under [`spec/decisions/`](spec/decisions/).
- **The [compatibility policy](docs/compatibility-policy.md).**
- **Releases**, described next.
- **This file.**

### Releases

The core maintainers decide when a release happens, what version it carries, and what goes in
it. The procedure is [docs/RELEASING.md](docs/RELEASING.md). Port maintainers with publish rights
run the publish for their port inside that decision. They do not publish a version the core
maintainers have not approved.

### The creator's tie-break and veto

The creator, Doug Mealing, has two extra powers, limited to three subjects: the model format,
ADRs and releases.

- **Tie-break.** When the core maintainers are split evenly on one of these subjects, the
creator decides.
- **Veto.** The creator can block a change to one of these subjects. A veto is written on the
issue or pull request with the reason.

Outside those three subjects, the creator has one vote like any other core maintainer.

## Ownership

The `metaobjectsdev` GitHub organization, the package namespaces (`@metaobjectsdev` on npm,
`com.metaobjects` on Maven Central, `metaobjects` on PyPI, and the `MetaObjects` packages on
NuGet), the `metaobjects.dev` and `metaobjects.com` domains, and the MetaObjects name and
trademark belong to Doug Mealing LLC. Roles in this file grant access to these. They do not
transfer ownership.

The code is licensed under the [Apache License 2.0](LICENSE). Contributors keep the copyright to
their contributions and license them to the project under that license. There is no copyright
assignment and no contributor license agreement. Anyone may fork the code under the license; the
license does not grant use of the MetaObjects name or trademark.

Paid work or sponsorship does not grant a role, a vote or an exception to review. A change built
for a paying customer goes through the same review as any other change.

## Succession

The creator has stepped away when they say so in writing, or when they have not committed,
reviewed or answered on the project for 6 months.

When that happens:

1. The remaining core maintainers run the project and decide by majority vote. The creator's
tie-break does not pass to anyone, so an even split leaves the proposal unaccepted and the
status quo stands.
2. Doug Mealing LLC gives the remaining core maintainers admin access to the GitHub organization
and owner access to every registry package, so that releases can continue.
3. If there is no other core maintainer, the port maintainers choose one or more of themselves as
core maintainers by majority vote, and step 2 applies to them.
4. If there are no maintainers at all, the README is updated to say the project is unmaintained.
The code stays available under the Apache License 2.0.

Ownership of the organization, the namespaces and the trademark stays with Doug Mealing LLC
throughout. The creator's veto does not pass to anyone.

## Stepping down and removal

### Stepping down

Any maintainer can step down at any time by opening a pull request that moves them to the
Emeritus section of [MAINTAINERS.md](MAINTAINERS.md). Their write access and registry ownership
are removed within one week.

### Inactivity

A maintainer who has not reviewed, merged or committed in their area for 6 months is asked
whether they want to stay. If they do not answer within one month, they move to Emeritus. They
can come back by asking; a core maintainer restores the role unless there is a reason not to.

### Removal

A maintainer can be removed for a breach of the [Code of Conduct](CODE_OF_CONDUCT.md), or for
misusing their rights, such as publishing a version outside an approved release or merging a
model-format change without core-maintainer approval. The core maintainers decide by majority,
not counting the person concerned. The person is told the reason directly, and the change to
[MAINTAINERS.md](MAINTAINERS.md) is made in a pull request.

If a registry account or repository access may be compromised, any core maintainer can suspend
that access at once. The decision on whether to restore it is made within two weeks.

## Changing this file

Changes to this file go through a pull request, stay open for at least 2 weeks, and need
approval from every core maintainer. The Ownership section can change only with Doug Mealing
LLC's agreement.

## Related files

- [MAINTAINERS.md](MAINTAINERS.md): who holds each role and each registry package today
- [CONTRIBUTING.md](CONTRIBUTING.md): how to propose a change
- [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)
- [SECURITY.md](SECURITY.md): how to report a vulnerability
53 changes: 53 additions & 0 deletions MAINTAINERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Maintainers

This file lists who holds each role in the project and who owns each registry package today.
[GOVERNANCE.md](GOVERNANCE.md) defines the roles and how they are earned. A change to this file
goes through a pull request like any other change.

## Core maintainers

| Name | GitHub | Contact |
|---|---|---|
| Doug Mealing (creator) | [`dmealing`](https://github.com/dmealing) | doug@dougmealing.com |

The creator is the only maintainer today and covers every area below until it has a port
maintainer. Every area is open.

## Areas

| Area | Paths | Port maintainer |
|---|---|---|
| TypeScript server port (loader, codegen, runtime, migrations, CLI) | `server/typescript/` | Maintainer wanted |
| Web client (React, TanStack, Angular, framework-agnostic core) | `client/web/` | Maintainer wanted |
| Java port (loader, OMDB, render, Spring codegen, Maven plugin) | `server/java/` except the Kotlin modules | Maintainer wanted |
| Kotlin port | `server/java/codegen-kotlin/`, `server/java/metadata-ktx/`, `server/java/omdb-ktx/` | Maintainer wanted |
| C# port | `server/csharp/` | Maintainer wanted |
| Python port | `server/python/` | Maintainer wanted |
| Metamodel spec and conformance corpora (core-maintainer approval always applies) | `spec/`, `fixtures/` | Maintainer wanted |
| Documentation and the docs-site generator | `docs/`, `server/typescript/packages/docs-site/` | Maintainer wanted |
| Libraries (`ai`, `iam`) | `library/` | Maintainer wanted |
| Agent context (skills, `AGENTS.md` sources, `llms.txt`) | `agent-context/` | Maintainer wanted |
| CI and release tooling | `scripts/`, `.github/` | Maintainer wanted |

A new generator family (for example Prisma or Django) can become its own area once someone
maintains it.

## Registry owners

As of 2026-10-28, every registry package has a single owner, the creator.

| Registry | Packages | Owner today | How it is published |
|---|---|---|---|
| npm | The 14 `@metaobjectsdev/*` packages: `ai-runtime`, `cli`, `codegen-ts`, `codegen-ts-react`, `codegen-ts-tanstack`, `docs-site`, `metadata`, `migrate-ts`, `react`, `render`, `runtime-ts`, `runtime-web`, `sdk`, `tanstack` | npm user `dougmealing`, the only owner of each package, in the `metaobjectsdev` npm organization | Locally, by the release script ([docs/RELEASING.md](docs/RELEASING.md)) |
| Maven Central | The `com.metaobjects` namespace: the `metaobjects` parent POM and 14 modules (`metaobjects-metadata`, `-codegen-base`, `-codegen-mustache`, `-codegen-spring`, `-codegen-kotlin`, `-codegen-plantuml`, `-render`, `-metadata-ktx`, `-maven-plugin`, `-core-spring`, `-spring-boot-starter`, `-om`, `-omdb`, `-omdb-ktx`) | The creator's Sonatype Central Portal account, which holds the verified namespace; artifacts are signed with the creator's GPG key | Locally, with `mvn deploy` |
| NuGet | `MetaObjects`, `MetaObjects.Render`, `MetaObjects.Codegen`, `MetaObjects.Cli` | nuget.org organization `metaobjects`, administered by the creator | Trusted Publishing from `.github/workflows/publish-csharp.yml` |
| PyPI | `metaobjects` | PyPI user `dougmealing` (Owner) | Locally or from `.github/workflows/publish-python.yml` with an API token |

`@metaobjectsdev/angular` and `@metaobjectsdev/codegen-ts-angular` are source-only and are not on
npm ([ADR-0048](spec/decisions/ADR-0048-angular-tier-source-only.md)).

The `metaobjectsdev` GitHub organization has one member and owner, `dmealing`.

## Emeritus

None yet.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,12 @@ named-constants-for-metamodel-strings, no-`any` rule, cross-language porting
contract, public-repo hygiene). For significant new features, open an issue
first to discuss the approach.

[`GOVERNANCE.md`](GOVERNANCE.md) sets out the roles (contributor, port maintainer, core
maintainer), how merge and publish rights are earned, how decisions are made, and what
happens if the creator steps away. [`MAINTAINERS.md`](MAINTAINERS.md) lists who maintains
each port and area today, and who owns each registry package. Every port is looking for a
maintainer.

## Roadmap

Current + planned work is tracked as [GitHub issues labelled `FR`](https://github.com/metaobjectsdev/metaobjects/issues?q=is%3Aissue+label%3AFR), with [milestones](https://github.com/metaobjectsdev/metaobjects/milestones) for releases. [`spec/roadmap.md`](spec/roadmap.md) holds the release direction and the index of feature specs.
Expand Down
Loading