A living checklist for cutting the first stable release. The strategy + the compatibility surface it commits to are in ADR-0035.
Thesis: scaffold-and-own (ADR-0034) shrank the surface 1.0 must keep stable to
the metamodel spine + CLI + wire format + the scaffold-and-own contract — the
generated code is owned/disposable, so its internals are no longer a public API. The
metaobjects-audit skill is the maturity signal that the surface has set. 1.0 is
gated less by features than by dropping the breaking-change rate so we can
promise "no breaking until 2.0."
Status legend: ✅ done · 🔶 in progress · ⬜ not started · ❓ [RATIFY] decision needed.
- ✅ A1. Version-line strategy — RATIFIED 2026-07-02: decouple. npm/PyPI/NuGet
0.15 → 1.0.0, Java/Kotlin7.7 → 8.0.0(both forward — Maven cannot go backwards;1.0.0 < 7.7.1in every resolver), tied by a sharedMetamodel 1.0spec version (OpenTelemetry / protobuf-editions model; the Java jump is the Angular 2→4 precedent). ADR-0035 §2 (rewritten). Unblocks G1; adds C4. - ✅ A2. FR-024 declared-API — RATIFIED: DEFER.
api.*/operation.*/binding.*stay reserved-but-unregistered post-1.0 (already absent fromexpected-registry.json; additive to add later). Removes the last candidate for a breaking round → unblocks the quiet period (G3). Tracked in #10. - ✅ A3. Deprecated
codegen-ts/generatorsexport — RATIFIED: REMOVE at the cut. Removed as part of the 1.0/8.0 major bump (G2), not before — removing an export is breaking, so the major absorbs it. Consumers use themeta init-scaffolded owned copies. - ✅ A4. Cross-port "own your codegen" — RATIFIED: idiomatic + documented. The
per-port split (TS
meta init; JVM/Python/C# via build config) is intentional, not a parity gap. → D4 written:docs/features/own-your-codegen.md.
- ✅ B1. Compat policy published —
docs/compatibility-policy.md: the covered surface (breaking ⇒ major), what is not covered, the Metamodel-spec-version- decouple scheme, and the MINOR-vs-PATCH rule. (Consumer-facing form of ADR-0035 §1.)
- ✅ B2.
0.x → 1.0migration guide written —docs/features/migrations/0.x-to-1.0.md: version re-baseline + verify strict-default, jsonb parsed-value, timestamp instant-default,@dbColumnTypeslim,index.*/@uniqueremoval, passthrough type-preservation (@convert), deprecated-export removal. FR-024 deferred → no declared-API vocab to migrate.
- ✅ C1.
registry-conformanceenforces the vocabulary byte-identically across all 5 ports. - 🔶 C2. No pending vocabulary churn. The metamodel-1.0 vocabulary program
(
0.15.0/7.7.0; ADR-0036/0037/0038) was the intended pre-1.0 vocabulary finalization —field.uri/field.inet,@stringFormat, instant-default timestamps +@localTime, the@dbColumnTypeslim, reverse-nav finders — and ADR-0037 now gives a durable framework for any future addition. Only A2 (FR-024) remains open. Audit the registry for anything still experimental. - 🔶 C3. The last breaking metamodel/wire move landed in the
0.15.xline —origin.passthroughis now type-preserving (#185; a divergentfield.<subType>or array-ness fails load withERR_PASSTHROUGH_TYPE_MISMATCH, generalizing/retiring the FR-015ERR_PARAMETER_REF_PASSTHROUGH_TYPE_MISMATCH; opt out with the acknowledgement-only@convertonorigin.passthrough). It followed0.15.1/7.7.1— theindex.*type +identity.secondarykey-purity (ADR-0040;@uniqueremoved →ERR_UNKNOWN_ATTR) — which followed0.15.0/7.7.0(the metamodel-1.0 vocabulary program + the ADR-0039 own-accessor fix) and0.14.0/7.6.0(verify strict-default, jsonb parsed-value). The passthrough move reset the quiet-period clock — the first no-breaking coordinated release must come after it (see G3). - ✅ C4.
metamodelVersionmarker SHIPPED (PR #145, all 5 ports,"0.9"). A single rolled-up spec-version string the loader/registry exposes and every port emits, asserted by the conformance matrix — the artifact that lets packages version independently while all claiming "implements Metamodel 1.0." Pre-cut the value is"0.9"(still0.x/ unstable, but near-final going into the quiet period; decoupled from every package line); the cut freezes it as1.0. Design (agreed 2026-07-02):- One rolled-up number, not per-provider.
Metamodel 1.0is a named freeze of the core provider set (distribution-version pattern, à la OTel spec releases / protobuf editions). It is a version tag on the existingfixtures/registry-conformance/expected-registry.jsonmanifest — which is already the byte-exact bill of materials every port is gated against — not a new per-provider versioning system. Per-provider precision lives in that manifest, machine-checked, never human-tracked. - Registry/runtime property, NOT a per-file stamp. It does not go in the YAML/JSON metadata documents (validity is decided by the loader's registered providers, so there is no yaml/json duplication to manage). (An optional per-file "targets Metamodel X.Y" is separable and YAGNI for 1.0.)
- Core vocabulary only. Downstream-added providers are outside the promise (ADR-0023) and do not change this number; an app may version its own providers if it cares — the library's concern is the core set.
- Scope: pick the exposure API per port (e.g.
registry.metamodelVersion), stamp the manifest, assert byte-equality of the string across all five ports inregistry-conformance.
- One rolled-up number, not per-provider.
- ⬜ C5. Adopt the minor-vs-patch cadence rule (ADR-0035 §3, going forward). Trigger
is new public surface, not code size: package MINOR only for newly-dependable
surface (codegen output, CLI flag, a newly-supported vocab member); package PATCH
for bugfix/refactor; the Metamodel spec version bumps only on a shared
vocabulary/wire change. The fast
7.3→7.7minor run was breaking velocity; decouple- this rule ends the churn.
- ✅ D1.
verifystrict-by-default +--lax/-Dmeta.laxconsistent across all 4 CLI ports (shipped 0.14.0/7.6.0). - 🔶 D2. CLI flag surface documented + frozen —
init/gen/verify(+ subverbs,--lax,--template-spec, target/output flags) per port, locked against the CLI architecture (ADR-0015) and surfaced in one matrix. - 🔶 D3. Scaffold-and-own contract stable (TS) — what
meta initscaffolds + theGeneratorinterface owned templates implement. A3 resolved: the deprecatedcodegen-ts/generatorsre-export is removed at the cut (G2). - ✅ D4. "Own your codegen" documented for every port (A4 ratified) —
docs/features/own-your-codegen.md: the TSmeta initflow + the JVM/Python/C# build-config equivalents, side by side.
- ✅ E1. All shared corpora green (metamodel, render, persistence, api-contract,
registry, verify) on
main. - ✅ E2. Cross-port api-contract jsonb gate wired for all 5 ports (TS/Python + Java/Kotlin/C#).
- 🔶 E3. Sweep for any per-port-only contract behavior that should be cross-port
gated before the freeze. The thesis keeps paying out: the ADR-0039 own-accessor
program (
0.15.0/7.7.0) added a sharedextends-inheritance conformance fixture and its independent cross-port review caught a real latent class the sweep missed (an M:N junction inheriting itsidentity.referencechildren was falsely rejected in all three non-TS ports; a Python runtime path dropped an inherited M:N) — assume more lurk, and lead every cross-port fix with a shared fixture.
- ✅ F1.
metaobjects-auditskill shipped + run against two real deep adopters. - 🔶 F2. A real adopter reaches "Deep/Exemplary" with the CI drift gate wired — the strongest evidence the surface is stable enough to promise. (Both audited adopters were Deep; neither had the drift gate enforced in CI yet — closing that on at least one adopter is the proof point.)
- ⬜ F3. Fold the audit findings that point at the framework back in (e.g. the jsonb runtime-write gaps the gate surfaced) so 1.0 ships without known adoption friction.
-
⬜ G1. Execute A1 (the decoupled cut): npm/PyPI/NuGet
→1.0.0, Java/Kotlin→8.0.0, freeze the spec version atMetamodel 1.0(C4). Both forward; no backwards move on any registry. -
⬜ G2. Remove the deprecated export if A3=remove (one-time).
-
✅ G3. A quiet period — at least one coordinated release after the last breaking move with no metamodel-breaking changes, to prove the rate has actually dropped. Requires A2/FR-024 to land additively or defer.
CLOCK RESET by
0.24.0(2026-08-21). The coordinated pre-1.0 breaking batch — ADR-0052 template direction, FR-038 requirement vocabulary, FR-037 R1@mutability, FR-037 R2origin.collection— is four metamodel-breaking retirements in one release, andmetamodelVersionmoved0.9→0.10for the first time ever. So the counter starts again from0.24.0, and 1.0 now needs at least one coordinated release AFTER it carrying no metamodel-breaking change.OPEN — does
0.24.1(2026-08-24) satisfy this, or reset it again? UNRATIFIED.0.24.1was the first coordinated release after0.24.0, so on the face of it it is the candidate quiet release. Two facts cut against that:- It moved
metamodelVersion0.11→0.12— the very axis G3 measures. (0.11was spent by #342 and0.12by #335; one release, one shipped contract number, but the number moved twice inside the window.) - Two previously-LOADING forms stopped loading —
@fieldstogether with@expron an index (#342), and@filterable/@sortableon anisArrayfield (#335 Half B). An adopter who wrote either has to edit metadata to upgrade.
The argument the other way is the doctrine this project has now applied four times — the
0.19.1@minclamp, the0.21.6likecase-sensitivity fix, and both of the above: a correction of previously-wrong acceptance is a bug fix, not a contract change. Neither form was ever validly expressible (one silently threw half of itself away; the other emitted SQL that cannot execute), and in both cases the fix is deleting an attribute that was doing nothing. On that reading0.24.1carried no metamodel-breaking change and G3 is satisfied.Recommendation (not a ruling — this is the maintainer's call): treat
0.24.1as NOT satisfying G3, and require one more coordinated release with nometamodelVersionmove. Two reasons. G3's stated purpose is "to prove the rate has actually dropped" — it measures churn in the contract, and a release that movesmetamodelVersionand forces adopter edits is evidence the rate has not dropped, whatever the edits are called. And the cost of being wrong is asymmetric: waiting one release costs a release, while cutting 1.0 off a window that actually was churning spends the 1.0 stability promise itself, which cannot be taken back.Whoever rules on this should record it here, in this bullet, rather than in a changelog — it is the gate on G1.
RULED (2026-08-26, maintainer):
0.24.2does NOT reset the clock, and IS the quiet release G3 asks for. FR-039 movesmetamodelVersion0.12→0.13, and that is the axis G3 measures — but the move is ADDITIVE.planned | live | partialkeep their meanings and their gates,@supersededByreturns on a status that did not previously exist, and no document that loads on0.24.1stops loading. Zero adopters must edit anything.G3's stated purpose is "to prove the rate has actually dropped", and the rate it measures is BREAKING churn — the thing that costs an adopter a migration. A release forcing no edits is evidence the rate dropped, not evidence against it. That is the distinction the
0.24.1discussion above could not settle cleanly, because0.24.1did force edits (two previously-loading forms stopped loading) whatever one calls them;0.24.2forces none, so the two cases do not need the same answer.The asymmetric-cost argument above still applies and is answered rather than waived: the risk of ruling wrongly here is cutting 1.0 off a window that was actually churning. It was not.
0.24.1is treated as NOT satisfying G3 (per the recommendation), and0.24.2— one coordinated release later, additive, adopter-edit-free — is the one that does. So G3 is satisfied by0.24.2, and G1 is unblocked on this gate.This cost was adjudicated, not discovered. The batch was ruled in knowing it would reset this clock, on the reasoning that under ADR-0023's sealed strict registry a retirement has no deprecation shim — so N breaking MINORs mean N adopter migrations, and batching converts four migrations into one. Paying one quiet period to buy that is the trade that was accepted. What would NOT be acceptable is discovering the reset later and treating it as a surprise; it is written here so the next reader sees a decision rather than an accident.
- It moved
-
⬜ G4. Cut Metamodel 1.0 through the
releasingskill (RC → smoke → confirm → promote), with the migration guide (B2) + compat policy (B1) published alongside.
Last updated 2026-08-21 (post the 0.24.0 coordinated pre-1.0 breaking batch — ADR-0052 + FR-038 + FR-037 R1/R2 — which reset the quiet-period clock again (G3) and moved metamodelVersion 0.9 → 0.10. Earlier: 0.15.1/7.7.1 + 0.15.2; the 0.15.x passthrough type-preservation move (#185) had reset it before — C3/G3; A1 ratified — decouple).
Owner: maintainer. Update the status marks as items land; ratify the remaining §A
decisions (A2–A4) to unblock the rest.