From 827734ac20ae1aa6f0344b821df594ec9e70bd3a Mon Sep 17 00:00:00 2001 From: Doug Mealing Date: Wed, 28 Oct 2026 07:09:35 -0400 Subject: [PATCH 1/2] docs: add GOVERNANCE.md and MAINTAINERS.md, link them from README and CONTRIBUTING GOVERNANCE.md sets out the three roles (contributor, port maintainer, core maintainer), how merge and publish rights are earned, lazy consensus with core-maintainer approval for the model format, ADRs and releases, the creator's scoped tie-break and veto, ownership of the org, namespaces and trademark, succession, and stepping down. MAINTAINERS.md lists the creator as the sole maintainer, every port and area as maintainer wanted, and today's registry owners. --- CONTRIBUTING.md | 7 +- GOVERNANCE.md | 187 ++++++++++++++++++++++++++++++++++++++++++++++++ MAINTAINERS.md | 53 ++++++++++++++ README.md | 6 ++ 4 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 GOVERNANCE.md create mode 100644 MAINTAINERS.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2b2ffc2c0..55dd7647f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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. @@ -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 diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 000000000..29f28edfc --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,187 @@ +# 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 decides. + +### 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 the tie-break passes to a majority vote + among them. +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 diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 000000000..47e653636 --- /dev/null +++ b/MAINTAINERS.md @@ -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. diff --git a/README.md b/README.md index 31cb92e14..be2e979eb 100644 --- a/README.md +++ b/README.md @@ -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. From 950964115268498b23c33052f6aa475a0d36e646 Mon Sep 17 00:00:00 2001 From: Doug Mealing Date: Wed, 28 Oct 2026 07:16:32 -0400 Subject: [PATCH 2/2] no-mistakes(review): Scope creator tie-break; fix succession even-split rule --- GOVERNANCE.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 29f28edfc..2d1f493a0 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -79,7 +79,9 @@ it is accepted. 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 decides. +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 @@ -136,8 +138,9 @@ reviewed or answered on the project for 6 months. When that happens: -1. The remaining core maintainers run the project, and the tie-break passes to a majority vote - among them. +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