Skip to content

Commit 8a3532d

Browse files
dmealingclaude
andcommitted
docs(roadmap): catch the FR registry up to 0.24.0/0.24.1, and open the G3 question
spec/roadmap.md calls itself the single source of truth for the roadmap and was last refreshed 2026-08-05 — before both 0.24.0 and 0.24.1. Its Shipped section had been updated for the breaking window; the FR registry table at the top had not, so the file contradicted itself and described two shipped things as pending: - FR-037 said its R2 re-entry shape "is filed as #335 and is ADDITIVE". #335 shipped in 0.24.1, and was additive exactly as predicted. - FR-038 said the @Verifiedby retirement "rides the SAME pre-1.0 MINOR as FR-037's R1/R2". It rode it, in 0.24.0, and landed. Both rows now lead with what shipped and where, and name what actually remains: FR-037 R3/R4/R5 and the FR-038 stub generator, all additive, all 1.1. Adds a 0.24.1 record beside the 0.24.0 one, because that release raises a question the roadmap should not bury: it moved metamodelVersion 0.11 -> 0.12 and made two previously-LOADING forms fail to load, while being cut as a PATCH on the previously-wrong-acceptance doctrine. That lands on docs/1.0-readiness.md §G3, whose clock reset to 0.24.0 and which needs one coordinated release after it with no metamodel-breaking change. Whether 0.24.1 IS that release depends on whether a previously-wrong-acceptance correction counts as metamodel-breaking for G3's purpose. §G3 now states the question, both arguments, and a recommendation — that it does NOT satisfy G3, because G3 measures whether contract churn has dropped and the cost of being wrong is asymmetric: one more release versus spending the 1.0 stability promise itself. Recorded as UNRATIFIED. It is the maintainer's call and it gates G1. Gates: scripts/ci-local.sh --only gates PASSED (12/12). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015WgNA6uDN9qxu2nA471rAq
1 parent 273f4b0 commit 8a3532d

2 files changed

Lines changed: 57 additions & 5 deletions

File tree

docs/1.0-readiness.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,36 @@ Status legend: ✅ done · 🔶 in progress · ⬜ not started · ❓ **[RATIFY]
154154
starts again from `0.24.0`, and 1.0 now needs at least one coordinated release AFTER it
155155
carrying no metamodel-breaking change.
156156

157+
**OPEN — does `0.24.1` (2026-08-24) satisfy this, or reset it again? UNRATIFIED.**
158+
`0.24.1` was the first coordinated release after `0.24.0`, so on the face of it it is the
159+
candidate quiet release. Two facts cut against that:
160+
161+
1. It moved **`metamodelVersion` `0.11``0.12`** — the very axis G3 measures. (`0.11` was
162+
spent by [#342](https://github.com/metaobjectsdev/metaobjects/issues/342) and `0.12` by
163+
[#335](https://github.com/metaobjectsdev/metaobjects/issues/335); one release, one shipped
164+
contract number, but the number moved twice inside the window.)
165+
2. **Two previously-LOADING forms stopped loading**`@fields` together with `@expr` on an
166+
index (#342), and `@filterable`/`@sortable` on an `isArray` field (#335 Half B). An adopter
167+
who wrote either has to edit metadata to upgrade.
168+
169+
The argument the other way is the doctrine this project has now applied four times — the
170+
`0.19.1` `@min` clamp, the `0.21.6` `like` case-sensitivity fix, and both of the above: a
171+
correction of previously-*wrong acceptance* is a bug fix, not a contract change. Neither form
172+
was ever validly expressible (one silently threw half of itself away; the other emitted SQL
173+
that cannot execute), and in both cases the fix is deleting an attribute that was doing
174+
nothing. On that reading `0.24.1` carried no metamodel-*breaking* change and G3 is satisfied.
175+
176+
**Recommendation (not a ruling — this is the maintainer's call): treat `0.24.1` as NOT
177+
satisfying G3, and require one more coordinated release with no `metamodelVersion` move.**
178+
Two reasons. G3's stated purpose is *"to prove the rate has actually dropped"* — it measures
179+
churn in the contract, and a release that moves `metamodelVersion` and forces adopter edits is
180+
evidence the rate has not dropped, whatever the edits are called. And the cost of being wrong
181+
is asymmetric: waiting one release costs a release, while cutting 1.0 off a window that
182+
actually was churning spends the 1.0 stability promise itself, which cannot be taken back.
183+
184+
Whoever rules on this should record it **here**, in this bullet, rather than in a changelog —
185+
it is the gate on G1.
186+
157187
**This cost was adjudicated, not discovered.** The batch was ruled in knowing it would
158188
reset this clock, on the reasoning that under ADR-0023's sealed strict registry a
159189
retirement has no deprecation shim — so N breaking MINORs mean N adopter migrations, and

spec/roadmap.md

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# MetaObjects Roadmap
22

3-
_Last refreshed 2026-08-05._
3+
_Last refreshed 2026-08-24._
44

55
> **This file is the single source of truth for the roadmap.** GitHub Milestones + Issues +
66
> the Project board mirror it. Keeping them in sync: `docs/ROADMAP-PROCESS.md`.
@@ -48,8 +48,8 @@ under **Shipped**; planned FRs under **Planned** + the **Release plan**. ✅ shi
4848
| FR-034 | Ecosystem tier — connected systems (`system`/`container`/`surface`/`environment`) | 📋 designed (**draft, deferred post-1.0**) | 1.1 ||
4949
| FR-035 | Present-key PATCH tristate (mutation surface) | 🟢 shipped 5 ports (absent→untouched / present-null→clears / null-on-`@required`→400); coordinated **breaking** release held for FR-036 | 1.0 ||
5050
| FR-036 | Constraint-validation enforcement + semantic pins | 🟢 shipped 5 ports in the coordinated `0.16.0`/`7.8.0` breaking release (required-string = non-empty·accept-whitespace · `@Pattern` = full-match · strictest-wins length; HTTP-tier enforcement all 5 ports; TPH tristate) | 1.0 ||
51-
| FR-037 | Projection expressiveness (`origin.rank`) + field write-access modes (`@mutability`) | ⚪ requirements (pre-design), decisions resolved. **R1/R2 retire registered vocabulary (`@readOnly`), so the breaking half must ride a coordinated pre-1.0 breaking MINOR** — post-1.0 a metamodel-vocabulary break moves `metamodelVersion`'s major (ADR-0035 §1 + Am. 2) and should still ride the pre-1.0 slot, where the caret rule is a real gate. `origin.rank` + the rest are additive → 1.1. **R2's designated re-entry shape — `@agg: collect` with `@of` OPTIONAL, i.e. whole-object rollup — is filed as [#335](https://github.com/metaobjectsdev/metaobjects/issues/335) and is ADDITIVE**, so it does not ride the breaking slot: `@of` is already `required: false` in the registry, the constraint lives in validation, and relaxing it makes previously-invalid metadata valid. Design: `docs/superpowers/specs/2026-08-10-fr-037-projection-expressiveness-and-write-once-design.md` | 1.0 · 1.1 | [#335](https://github.com/metaobjectsdev/metaobjects/issues/335) |
52-
| FR-038 | Requirement-derived test stubs (inverts `@verifiedBy`) | ⚪ proposed. Generate the test from the requirement so the link is structural, not a name the author picks — an audit of one 19-name ledger found 4 names that did not verify their claim. **The `@verifiedBy` retirement is breaking and rides the SAME pre-1.0 MINOR as FR-037's R1/R2, not a second one**; the stub generator is additive → 1.1. Design: `docs/superpowers/specs/2026-08-15-fr-038-requirement-derived-test-stubs-design.md` | 1.0 · 1.1 ||
51+
| FR-037 | Projection expressiveness (`origin.rank`) + field write-access modes (`@mutability`) | 🟢 R1 + R2 shipped `0.24.0`; #335 shipped `0.24.1`; R3/R4/R5 open. **R1/R2 retire registered vocabulary (`@readOnly`), so the breaking half must ride a coordinated pre-1.0 breaking MINOR** — post-1.0 a metamodel-vocabulary break moves `metamodelVersion`'s major (ADR-0035 §1 + Am. 2) and should still ride the pre-1.0 slot, where the caret rule is a real gate. `origin.rank` + the rest are additive → 1.1. **R1 and R2 SHIPPED in the coordinated `0.24.0` breaking MINOR** (`@readOnly` → `@mutability`; `origin.collection` → reserved-not-registered). **R2's designated re-entry shape — `@agg: collect` with `@of` OPTIONAL, the whole-object rollup, [#335](https://github.com/metaobjectsdev/metaobjects/issues/335) — SHIPPED in `0.24.1`** and was additive as predicted: `@of` was already `required: false` in the registry, the constraint lived in validation, and relaxing it made previously-invalid metadata valid. **R3/R4/R5 remain**, all additive → 1.1. Design: `docs/superpowers/specs/2026-08-10-fr-037-projection-expressiveness-and-write-once-design.md` | 1.0 · 1.1 | [#335](https://github.com/metaobjectsdev/metaobjects/issues/335) |
52+
| FR-038 | Requirement-derived test stubs (inverts `@verifiedBy`) | 🟢 the vocabulary retirement shipped `0.24.0`; the stub generator remains. Generate the test from the requirement so the link is structural, not a name the author picks — an audit of one 19-name ledger found 4 names that did not verify their claim. **The `@verifiedBy` retirement was breaking and rode the SAME pre-1.0 MINOR as FR-037's R1/R2, not a second one — SHIPPED in `0.24.0`** (`@verifiedBy`, `@supersededBy`, and `@status: abandoned|superseded` all deregistered). The stub generator is additive and remains → 1.1. Design: `docs/superpowers/specs/2026-08-15-fr-038-requirement-derived-test-stubs-design.md` | 1.0 · 1.1 ||
5353

5454
_(FR-001 was the original metamodel foundation — pre-dates the FR-numbered tracking.)_
5555
_(FR-032 was developed under the working number "FR-026" — see commit history; renumbered to avoid the FR-026=Forms collision. Design: `docs/superpowers/specs/2026-06-13-fr-032-canonical-fqn-refs-design.md`, ADR-0032.)_
@@ -258,8 +258,30 @@ perform.
258258
Still open from FR-037: **R3/R4/R5** and the FR-038 **requirement-test stub generator**
259259
remain 1.1 work, and all of them are additive — none needs a breaking slot.
260260
[#335](https://github.com/metaobjectsdev/metaobjects/issues/335) (`@agg: collect` with `@of`
261-
optional) is likewise additive and is the designated re-entry shape for the capability
262-
`origin.collection` named.
261+
optional) was the designated re-entry shape for the capability `origin.collection` named, and
262+
**shipped in `0.24.1`** — see the section below.
263+
264+
### `0.24.1` (2026-08-24) — the re-entry shape lands, and a G3 question opens
265+
266+
Coordinated PATCH across all four registries (npm / PyPI / NuGet `0.24.1`, Maven `7.24.1`).
267+
Headline is **[#335](https://github.com/metaobjectsdev/metaobjects/issues/335), the whole-object
268+
rollup**`@of` becomes OPTIONAL on `@agg: collect`, closing the one coverage gap
269+
`origin.collection`'s retirement had to state rather than close. Additive, as FR-037 predicted.
270+
271+
**But the release also moved `metamodelVersion` `0.11``0.12` and made two previously-LOADING
272+
forms fail to load** — an index key carrying both `@fields` and `@expr`
273+
([#342](https://github.com/metaobjectsdev/metaobjects/issues/342)), and `@filterable`/`@sortable`
274+
on an `isArray` field (#335 Half B). Both were cut as PATCH on the previously-wrong-acceptance
275+
doctrine this project has now applied four times (the `0.19.1` `@min` clamp, the `0.21.6` `like`
276+
case-sensitivity fix, and both of these): each corrects acceptance that was always wrong rather
277+
than changing a contract, and in both cases the adopter fix is deleting an attribute that was
278+
doing nothing.
279+
280+
**That opens a question §G3 has to answer explicitly, and it is not answered yet** — see
281+
[`docs/1.0-readiness.md`](../docs/1.0-readiness.md) §G3. The quiet-period clock reset to `0.24.0`;
282+
whether `0.24.1` is the quiet release that satisfies it, or resets it again, depends on whether a
283+
previously-wrong-acceptance correction counts as "metamodel-breaking" for G3's purpose. **This is
284+
unratified.** The recommendation recorded there is the conservative one: it does NOT satisfy G3.
263285

264286
### What the window carried, and why it precedes GA
265287

0 commit comments

Comments
 (0)