Skip to content

Commit 5ea77bb

Browse files
dmealingclaude
andcommitted
docs(changelog): drop a committed diff3 marker, and state the regen consequence
`CHANGELOG.md:175` carried an orphan `||||||| <sha>` conflict marker on `main` — the rest of that diff3 merge was resolved and this line was not. It left the release notes with two `### Added`, two `### Changed` and two `### Fixed` sections, and one Fixed bullet stranded outside any heading. The sections are merged back into one of each, in the original order within each; no bullet text changed and no line was dropped. Adds the consequence the notes did not state: 1.0.4 changes GENERATED OUTPUT. Every generated file's header comment moved (#367) and routes files gain the auth-seam JSDoc, so `verify --codegen` reports drift on any project that commits its generated output until `meta gen` is re-run. Measured on an adopter upgrading 1.0.2 -> the RC: exit 0 -> exit 1 across 33 files, with a regen diff of zero non-comment lines. The two shapes that do change for real — #368's duplicate `identity.reference` FK correlation and the inherited-M:N derivation — are named rather than left for an adopter to discover in a migration diff. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011cQxyVuTkdPmAduLiedNEg
1 parent 64ab244 commit 5ea77bb

1 file changed

Lines changed: 82 additions & 83 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 82 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@ here.**
1010

1111
## [Unreleased]
1212

13+
**Upgrading: run `meta gen`.** Every generated file's header comment changed ([#367]), and
14+
generated routes files gain an auth-seam JSDoc block, so `meta verify --codegen` reports
15+
drift on any project that commits its generated output until it is regenerated. For most
16+
projects that regen diff is **comments only — zero non-comment lines**. Two shapes change
17+
for real: a model with two `identity.reference` nodes onto the same target gets corrected
18+
FK wiring and referential actions ([#368] — including an `ON DELETE` / `ON UPDATE` diff on
19+
the next `meta migrate`), and an M:N relationship inherited through `extends` now derives
20+
navigation that was previously dropped from the output with no error.
21+
1322
### Added
1423

1524
- **Libraries: reusable declared design you opt into** (FR-043, the sixth pillar).
@@ -47,6 +56,37 @@ here.**
4756
(Kotlin inherits the JVM's); one new conformance fixture takes over the unmarked-conflict
4857
error branch, so the coverage moved rather than being deleted.
4958

59+
- **`layer` joins the cross-port generator manifest** — `model` / `persistence` / `api` /
60+
`client` / `docs` / `capability` — gated by all five ports' registry-conformance tests
61+
exactly as `tier` is. Five TypeScript generators that were in no manifest at all (`form`,
62+
`hooks`, `grid`, `grid-hook`, `requirement-tests`) join it too, so the catalog describes
63+
34 generators where the manifest described 29.
64+
65+
- **`meta gen` audits the selection.** Two self-extinguishing warnings, neither a build
66+
failure: a wired generator whose `requires` are not wired (its output will import a
67+
module nothing emits), and two `api`-layer generators declaring different frameworks
68+
(`routes` + `routes-hono` emit to different paths, so nothing conflicts and two complete
69+
HTTP surfaces appear silently). There is deliberately no equivalent rule on the `client`
70+
layer: `@metaobjectsdev/tanstack` peers on `react`, so a form generator plus the TanStack
71+
hook/grid generators is the intended composition.
72+
73+
- **The auth seam is printed in the generated routes handler's JSDoc ([#367]).** Stock
74+
CRUD is unauthenticated and no metadata attribute should change that — authentication
75+
is not derivable from a model (ADR-0023). Both frameworks already compose a guard
76+
around the generated mount; only the generated output never said so. Fastify hooks are
77+
encapsulated per plugin scope and inherited by child scopes, so wrapping the call
78+
reaches through the handler's own `register(..., { prefix })`; Hono's trailing wildcard
79+
matches the collection path itself, so one `app.use` covers list, get and every write.
80+
Both recipes are executed as tests (`runtime-ts/test/route-auth-seam.test.ts`) rather
81+
than asserted in prose, and each names the generator that emitted the file
82+
(`routesFile` / `routesFileHono`) for narrowing with `expose`. The JSDoc also states
83+
what no mount can express: a row-ownership rule is not a property of a route, so those
84+
verbs are hand-written and the generated file narrowed around them.
85+
- **`mountReadOnlyCrudRoutes` accepts `routeOptions`** (`@metaobjectsdev/runtime-ts`,
86+
Fastify), the option `mountCrudRoutes` and `mountM2mRoute` already took. A projection's
87+
generated routes could not carry a route-level hook the way an entity's could — an
88+
inconsistency, not a policy. Read-only is not public.
89+
5090
### Changed
5191

5292
- **`libraries` moved to `.metaobjects/config.json`**, out of `metaobjects.config.ts`,
@@ -86,6 +126,48 @@ here.**
86126
node's error envelope read differently depending on how the library was resolved — and
87127
collided with an adopter file of that name.
88128

129+
- **Codegen is OPT-IN: no port ships a default generator suite** (ADR-0034 Amendment 2).
130+
A new project got code it never asked for — TypeScript's `meta init` copied and wired
131+
five generators, C# ran nine for a caller who named none, Python eight; Java never had
132+
a default set and has been right all along. Deciding which code an application needs
133+
belongs to whoever is building it, increasingly an LLM in the repo, which is well able
134+
to make that call given a truthful catalog and is badly served by a default that
135+
pre-empts it.
136+
137+
**This is a PATCH and no existing project changes by one byte.** An adopter already has
138+
their owned copies on disk and their selection committed in their own config; `meta gen`
139+
keeps running exactly that list, `verify --codegen` keeps checking exactly that output,
140+
and re-running `init` never clobbers a file that exists. What changes is what a *new*
141+
project starts with. `docs/compatibility-policy.md` is narrowed in the same change: the
142+
scaffold-and-own promise is the LAYOUT and the INTERFACES, not which generators a fresh
143+
scaffold wires.
144+
145+
What this means per port:
146+
- **TypeScript** — `meta init` scaffolds `codegen/generators/` **empty**, a config with
147+
`generators: []`, and no dependencies. `dbImport` and the throwing `src/db.ts` stub are
148+
gone with it: both existed only because the scaffold wired `routesFile()`, whose output
149+
emits `import { db } from …`. `dbImport` is now a declared `configKey` on the `routes`
150+
catalog entry, reported by `meta eject routes` to the adopter who chose routes.
151+
- **C# / Python** — `--generators` is REQUIRED; a run that names none is a usage error
152+
and writes nothing. `verify --codegen` re-runs the SELECTION, so with none named it
153+
reports that there is nothing to check rather than regenerating a suite the project
154+
never ran. Python's `verify` gains `--generators`, matching C#.
155+
156+
- **`meta gen --list` is now the generator CATALOG, and `--probe` answers it against your
157+
own model.** `--list --format json` emits one document per generator: its `layer`,
158+
`framework`, what it emits, what it `requires`, the consolidated install set, the config
159+
keys it reads, and whether this project already owns a copy. `--probe` constructs every
160+
generator and dry-runs it against the loaded model, reporting how many files each would
161+
emit — so `output-parser: 3, callable: 0, requirement-tests: 7` replaces a category
162+
label, and cannot go stale, because it runs the generators rather than describing them.
163+
164+
- **`meta eject` takes many names and reports one consolidated install set.** A real
165+
selection is several generators, and three separate invocations produced three separate
166+
install lines for the same package. `--format json` carries, per file, the import line
167+
and the entry to wire, plus one install set with third-party ranges read from the runtime
168+
package's own `peerDependencies`. An unknown name refuses the whole call before writing
169+
anything.
170+
89171
### Fixed
90172

91173
- **An M:N relationship inherited through `extends` derived its junction FK columns
@@ -172,8 +254,6 @@ here.**
172254
No vocabulary change: `metamodelVersion` stays `1.0` and the registry manifest is
173255
untouched.
174256

175-
||||||| 7dafb055e
176-
177257
- **Both shipped libraries failed `meta verify`'s requirement gate**, in metadata an
178258
adopter cannot fix: every L4 in `ai` claimed FIELDS (`ERR_REQUIREMENT_L4_NOT_OBJECT`),
179259
and both libraries wrote their concerns as SIBLINGS of the L2 segment their own comments
@@ -185,68 +265,6 @@ here.**
185265
warnings, zero gate findings, zero lint findings, no unruled gaps, and every entity
186266
claimed by its own ledger.
187267

188-
### Changed
189-
190-
- **Codegen is OPT-IN: no port ships a default generator suite** (ADR-0034 Amendment 2).
191-
A new project got code it never asked for — TypeScript's `meta init` copied and wired
192-
five generators, C# ran nine for a caller who named none, Python eight; Java never had
193-
a default set and has been right all along. Deciding which code an application needs
194-
belongs to whoever is building it, increasingly an LLM in the repo, which is well able
195-
to make that call given a truthful catalog and is badly served by a default that
196-
pre-empts it.
197-
198-
**This is a PATCH and no existing project changes by one byte.** An adopter already has
199-
their owned copies on disk and their selection committed in their own config; `meta gen`
200-
keeps running exactly that list, `verify --codegen` keeps checking exactly that output,
201-
and re-running `init` never clobbers a file that exists. What changes is what a *new*
202-
project starts with. `docs/compatibility-policy.md` is narrowed in the same change: the
203-
scaffold-and-own promise is the LAYOUT and the INTERFACES, not which generators a fresh
204-
scaffold wires.
205-
206-
What this means per port:
207-
- **TypeScript** — `meta init` scaffolds `codegen/generators/` **empty**, a config with
208-
`generators: []`, and no dependencies. `dbImport` and the throwing `src/db.ts` stub are
209-
gone with it: both existed only because the scaffold wired `routesFile()`, whose output
210-
emits `import { db } from …`. `dbImport` is now a declared `configKey` on the `routes`
211-
catalog entry, reported by `meta eject routes` to the adopter who chose routes.
212-
- **C# / Python** — `--generators` is REQUIRED; a run that names none is a usage error
213-
and writes nothing. `verify --codegen` re-runs the SELECTION, so with none named it
214-
reports that there is nothing to check rather than regenerating a suite the project
215-
never ran. Python's `verify` gains `--generators`, matching C#.
216-
217-
- **`meta gen --list` is now the generator CATALOG, and `--probe` answers it against your
218-
own model.** `--list --format json` emits one document per generator: its `layer`,
219-
`framework`, what it emits, what it `requires`, the consolidated install set, the config
220-
keys it reads, and whether this project already owns a copy. `--probe` constructs every
221-
generator and dry-runs it against the loaded model, reporting how many files each would
222-
emit — so `output-parser: 3, callable: 0, requirement-tests: 7` replaces a category
223-
label, and cannot go stale, because it runs the generators rather than describing them.
224-
225-
- **`meta eject` takes many names and reports one consolidated install set.** A real
226-
selection is several generators, and three separate invocations produced three separate
227-
install lines for the same package. `--format json` carries, per file, the import line
228-
and the entry to wire, plus one install set with third-party ranges read from the runtime
229-
package's own `peerDependencies`. An unknown name refuses the whole call before writing
230-
anything.
231-
232-
### Added
233-
234-
- **`layer` joins the cross-port generator manifest** — `model` / `persistence` / `api` /
235-
`client` / `docs` / `capability` — gated by all five ports' registry-conformance tests
236-
exactly as `tier` is. Five TypeScript generators that were in no manifest at all (`form`,
237-
`hooks`, `grid`, `grid-hook`, `requirement-tests`) join it too, so the catalog describes
238-
34 generators where the manifest described 29.
239-
240-
- **`meta gen` audits the selection.** Two self-extinguishing warnings, neither a build
241-
failure: a wired generator whose `requires` are not wired (its output will import a
242-
module nothing emits), and two `api`-layer generators declaring different frameworks
243-
(`routes` + `routes-hono` emit to different paths, so nothing conflicts and two complete
244-
HTTP surfaces appear silently). There is deliberately no equivalent rule on the `client`
245-
layer: `@metaobjectsdev/tanstack` peers on `react`, so a form generator plus the TanStack
246-
hook/grid generators is the intended composition.
247-
248-
### Fixed
249-
250268
- **Generated files no longer point at a plugin point that does not exist ([#367]).**
251269
Every emitted header carried `Customize via <Entity>.extra.ts in this directory`, and
252270
routes files added `(e.g., auth, additional handlers)`. Nothing in any toolchain imports
@@ -316,25 +334,6 @@ here.**
316334
changed product files or not — that consequence is recorded here so it isn't a
317335
surprise at release time. `metamodelVersion` stays `1.0`.
318336

319-
### Added
320-
321-
- **The auth seam is printed in the generated routes handler's JSDoc ([#367]).** Stock
322-
CRUD is unauthenticated and no metadata attribute should change that — authentication
323-
is not derivable from a model (ADR-0023). Both frameworks already compose a guard
324-
around the generated mount; only the generated output never said so. Fastify hooks are
325-
encapsulated per plugin scope and inherited by child scopes, so wrapping the call
326-
reaches through the handler's own `register(..., { prefix })`; Hono's trailing wildcard
327-
matches the collection path itself, so one `app.use` covers list, get and every write.
328-
Both recipes are executed as tests (`runtime-ts/test/route-auth-seam.test.ts`) rather
329-
than asserted in prose, and each names the generator that emitted the file
330-
(`routesFile` / `routesFileHono`) for narrowing with `expose`. The JSDoc also states
331-
what no mount can express: a row-ownership rule is not a property of a route, so those
332-
verbs are hand-written and the generated file narrowed around them.
333-
- **`mountReadOnlyCrudRoutes` accepts `routeOptions`** (`@metaobjectsdev/runtime-ts`,
334-
Fastify), the option `mountCrudRoutes` and `mountM2mRoute` already took. A projection's
335-
generated routes could not carry a route-level hook the way an entity's could — an
336-
inconsistency, not a policy. Read-only is not public.
337-
338337
[#367]: https://github.com/metaobjectsdev/metaobjects/issues/367
339338
[#368]: https://github.com/metaobjectsdev/metaobjects/issues/368
340339

0 commit comments

Comments
 (0)