Skip to content

Commit 806f1be

Browse files
dmealingclaude
andcommitted
feat(1.0)!: remove the four deprecated generator exports; the copy an adopter owns was missing a branch
G2 of docs/1.0-readiness.md. `entityFile` / `queriesFile` / `routesFile` / `barrel` leave `@metaobjectsdev/codegen-ts/generators`. Ratified as A3, promised in `0.x-to-1.0.md` §11. BREAKING: those four imports no longer resolve. `meta init` scaffolds owned copies and `meta eject <name>` copies one at any time. The checklist's shorthand — "remove the deprecated codegen-ts/generators export" — would have deleted the subpath, and that is wrong. It carries ~20 exports and only those four were deprecated; the prompt/output tier (promptRender, outputParser, outputPrompt, extractor, renderHelper, traceHelperFile) plus routesFileHono, namesFile and callableFile have NO other public import path, and the CLI's own prompt-gate warning tells adopters to import promptRender from exactly there. Of six adopter estates surveyed, five import only non-deprecated names from that subpath and one imports the four: a path-wide removal breaks all six and the owned-copy remedy applies to one. A3's intent and the published guide both name the four. Removing the export made this repo a consumer of its own reference templates, and that immediately found a defect the removal turns from cosmetic into load-bearing: src/reference/queries.ts — the file `meta eject queries` hands an adopter — omitted the @autoset branch the built-in composer has. No insertPreserving<Entity>, no <Entity>InsertPreservingSchema import, no error: the module simply lacked the function. Two primitives it needs (renderInsertPreservingFn, hasAutoSetFields) were not public either, so an owned copy could not restore it by hand. With the built-in export gone the owned copy is the ONLY path, so the degraded output becomes the only output. reference-byte-identical.test.ts exists for exactly this and was green: not one of its seven fixtures carried @autoset, the sole trigger. That is not an oversight to patch — the whole corpus was written to exercise SHAPE (packages, FKs, value objects, extends) and @autoset is a per-field write RULE, so no shape-driven corpus grows one by accident. A fixture that carries one is added; it was confirmed red before the fix and green after. An audit of all six reference templates against their built-ins over both example models found no other divergence. Also fixed: metaobjects-audit told an auditing agent that ANY hit on `grep -r '@metaobjectsdev/codegen-ts/generators'` means the project has not adopted scaffold-and-own. Five of the six surveyed estates hit that grep while importing only non-ownable generators — a false finding against a correct project, whose recommended remedy would have changed nothing. It now matches the four NAMES. In-repo consumers move to the copies rather than to an engine internal, so the suites exercise what an adopter runs: a private @metaobjectsdev/test-generators package holds this repo's owned copies (byte-gated against readReferenceTemplate by a DISCOVERING test, so a new copy anywhere it scans is guarded the moment it lands), both examples get real codegen/generators/ copies, and cli temp-project configs use the stable-name registry. verify --codegen and the showcase pristine-regen root now carry codegen/ forward — without it a regen reports a config error as drift. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01At3v6M6uqECZ2Sb5eUv6YY
1 parent cf8fe29 commit 806f1be

120 files changed

Lines changed: 2239 additions & 233 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎CHANGELOG.md‎

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,58 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
77

88
## [Unreleased]
99

10+
### Removed — the deprecated `codegen-ts/generators` export of the four ownable generators
11+
12+
`entityFile`, `queriesFile`, `routesFile` and `barrel` are no longer exported from
13+
`@metaobjectsdev/codegen-ts/generators`. They carried an `@deprecated` marker since ADR-0034
14+
landed; removing them is the ratified 1.0 move (ADR-0035 A3, `docs/1.0-readiness.md` G2).
15+
**Migration is one file each:** `meta init` scaffolds owned copies into
16+
`codegen/generators/*.ts`, and `meta eject <name>` copies one at any time. Guide:
17+
[`docs/features/migrations/0.x-to-1.0.md`](docs/features/migrations/0.x-to-1.0.md) §11.
18+
19+
**The `/generators` subpath itself is NOT removed and is not deprecated.** It stays the
20+
supported public home of the generators that have no ownable copy — the prompt/output tier
21+
(`promptRender`, `outputParser`, `outputPrompt`, `extractor`, `renderHelper`,
22+
`traceHelperFile`) plus `routesFileHono`, `namesFile` and `callableFile`. The CLI's own
23+
prompt-gate warning names that import path, so deleting the subpath would have contradicted
24+
the product's own instructions. Scoping this by NAME rather than by path is load-bearing: of
25+
six adopter estates surveyed before the cut, **five import only non-deprecated names from
26+
that subpath and one imports the four**; a path-wide removal would have broken all six and
27+
the owned-copy remedy would have applied to one.
28+
29+
### Fixed — an ejected `queries` generator silently dropped `insertPreserving<Entity>` (#203)
30+
31+
`src/reference/queries.ts` — the template `meta init` scaffolds and `meta eject queries`
32+
copies — omitted the `@autoSet` branch the built-in composer has: no
33+
`insertPreserving<Entity>` function and no `<Entity>InsertPreservingSchema` import. So an
34+
adopter who owned their queries generator lost the #203 escape hatch on exactly the entities
35+
that have one, with **no error** — the emitted module simply lacked the function. Two engine
36+
primitives it needs (`renderInsertPreservingFn`, `hasAutoSetFields`) were not public either,
37+
so an owned copy could not have restored it by hand.
38+
39+
This matters more at 1.0 than it did before: with the built-in export removed, the owned copy
40+
is the ONLY path, so the degraded output becomes the only output.
41+
42+
**Why the gate that exists for this was green.** `reference-byte-identical.test.ts` runs every
43+
reference template AND the built-in it was copied from over a fixture corpus and requires
44+
byte-identical output — and **not one of its seven fixtures carried `@autoSet`**, which is the
45+
sole trigger for the branch. The reason outlives the fixture: every model in that corpus was
46+
written to exercise SHAPE (packages, FKs, value objects, `extends`), and `@autoSet` is a
47+
per-field write RULE, so no shape-driven corpus grows one by accident. A fixture that carries
48+
one is added, and was confirmed to fail before the fix and pass after.
49+
50+
`renderInsertPreservingFn` and `hasAutoSetFields` are now public engine primitives.
51+
52+
### Fixed — the audit skill convicted correct projects of not owning their codegen
53+
54+
`metaobjects-audit` told an auditing agent that any hit on
55+
`grep -r '@metaobjectsdev/codegen-ts/generators'` "means the project has not adopted
56+
scaffold-and-own." Five of six surveyed adopter estates hit that grep while importing only
57+
generators that have no ownable copy — a false finding against a correct project, and the
58+
recommended remedy (`meta init`) would not have changed anything. The check now matches the
59+
four removed NAMES, and the skill states outright that importing the non-ownable tier from
60+
that subpath is correct.
61+
1062
### Fixed — two doors disagreed about whether an object has one address (all five ports)
1163

1264
`primaryRdbSource` — the shared authority every consumer asks "which source is this object's

‎agent-context/skills/metaobjects-audit/SKILL.md‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ Actual cutovers run through the existing skills mapped per finding tier (§ Brid
2323
`com.metaobjects:*` / `metaobjects` / `MetaObjects.*` deps).
2424
- [ ] Count metadata source lines + all `@generated` / `DO NOT EDIT` files repo-wide.
2525
- [ ] **Owned-generators check:** does the project own generators at `codegen/generators/*`
26-
(scaffold-and-own via `meta init`), or still import the **deprecated** package export
27-
(`@metaobjectsdev/codegen-ts/generators`)? Not owning is itself a finding.
26+
(scaffold-and-own via `meta init`), or still import `entityFile` / `queriesFile` /
27+
`routesFile` / `barrel` from `@metaobjectsdev/codegen-ts/generators`? Those four were
28+
REMOVED at 1.0, so an import of them is an upgrade blocker, not just a style finding.
29+
**Match the four NAMES, never the subpath alone** — that subpath is the supported home of
30+
the non-ownable generators (`promptRender`, `outputParser`, `routesFileHono`, …), so
31+
flagging a hit on the path convicts a correct project.
2832
- [ ] **Cross-language version consistency (silent-drift check).** If the project uses MetaObjects in more than one language (e.g. a TS web client + a Java/Python/C# backend), enumerate EVERY MetaObjects package across ALL ecosystems (npm `@metaobjectsdev/*`, Maven `com.metaobjects:*`, PyPI `metaobjects`, NuGet `MetaObjects.*`) and record each version. **The version-number LINES differ by ecosystem (npm/PyPI/NuGet `0.x`/`1.x` vs Maven `7.x`/`8.x`), so you CANNOT eyeball drift** — a `0.12` next to a `7.7` looks fine but can be badly out of sync. Compare the **`metamodelVersion`** each port reports (the shared spec version on the registry manifest): a mismatch is real cross-language drift and a **finding** — the ports disagree on vocabulary/wire behavior. Also flag any port not on the latest release for its ecosystem. (This is a known real-world failure mode: newest backend, stale client, invisible because the numbers differ.)
2933
- [ ] Classify: **Greenfield** (none/minimal) · **Partial** · **Deep** → choose path below.
3034

@@ -343,8 +347,11 @@ Per finding: `file:line` → what → generated-equivalent exists? → recommend
343347

344348
## Owned-codegen & scaffold-and-own assessment
345349

346-
- If config imports deprecated `@metaobjectsdev/codegen-ts/generators` instead of
347-
owned `codegen/generators/*`, recommend the scaffold-and-own migration (`meta init`).
350+
- If config imports `entityFile` / `queriesFile` / `routesFile` / `barrel` from
351+
`@metaobjectsdev/codegen-ts/generators` instead of owned `codegen/generators/*`,
352+
recommend the scaffold-and-own migration (`meta init`, or `meta eject <name>`) — on 1.0+
353+
those four no longer resolve. Importing the non-ownable generators from that subpath is
354+
correct and is not a finding.
348355
- Audit owned generators: (a) regenerate clean? (b) drifted from reference templates —
349356
intentional (good) vs stale/accidental (missed upstream fix)? (c) hand-rolling a walk
350357
that a declarative `scope` + `outputPattern` could replace? (d) bespoke shape better as

‎agent-context/skills/metaobjects-audit/references/typescript.md‎

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,22 +69,34 @@ import { entityFile } from "./codegen/generators/entity";
6969
import { queriesFile } from "./codegen/generators/queries";
7070
```
7171

72-
**Deprecated import path** (still works, removal planned):
72+
**Removed import path.** `entityFile` / `queriesFile` / `routesFile` / `barrel` were
73+
exported from `@metaobjectsdev/codegen-ts/generators` and deprecated; **1.0 removed them**
74+
(ADR-0035 A3). On 1.0+ this no longer resolves:
7375

7476
```ts
7577
import { entityFile, queriesFile, routesFile, barrel } from "@metaobjectsdev/codegen-ts/generators";
7678
```
7779

78-
**Finding this in a project:** grep for the deprecated path:
80+
**Do NOT flag the subpath itself.** `@metaobjectsdev/codegen-ts/generators` is the supported,
81+
non-deprecated home of the generators that have no ownable copy — the prompt/output tier
82+
(`promptRender`, `outputParser`, `outputPrompt`, `extractor`, `renderHelper`,
83+
`traceHelperFile`) plus `routesFileHono`, `namesFile` and `callableFile`. The CLI's own
84+
prompt-gate warning tells adopters to import `promptRender` from exactly this path. A
85+
project importing those from it is CORRECT, and reporting it as un-adopted scaffold-and-own
86+
is a false finding.
87+
88+
**Finding this in a project:** grep for the four removed NAMES on that path, never the path
89+
alone:
7990

8091
```bash
81-
grep -r '@metaobjectsdev/codegen-ts/generators' .
92+
grep -rn '@metaobjectsdev/codegen-ts/generators' . \
93+
| grep -E 'entityFile|queriesFile|routesFile|barrel'
8294
```
8395

84-
A hit means the project has not adopted scaffold-and-own — recommend `meta init`
85-
to scaffold the owned copies. The owned generator files themselves (`codegen/generators/*.ts`)
86-
are the second thing to audit: are they stale relative to the reference templates,
87-
or intentionally customized?
96+
A hit is a 1.0 upgrade blocker (the import fails to resolve) — recommend `meta init` (or
97+
`meta eject <name>`) to scaffold the owned copies, then import those locally. The owned
98+
generator files themselves (`codegen/generators/*.ts`) are the second thing to audit: are
99+
they stale relative to the reference templates, or intentionally customized?
88100

89101
---
90102

‎agent-context/skills/metaobjects-codegen/references/typescript.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,12 @@ PROJECT ROOT that CONTAINS the metadata — never the metadata directory itself.
8484
## The generators
8585

8686
Server-side, framework-neutral. The first four are **scaffolded into your repo** by
87-
`meta init` and imported from `./codegen/generators/*` (ADR-0034); the rest come from the
88-
package main entry, `@metaobjectsdev/codegen-ts`. Do **not** import any of them from
89-
`@metaobjectsdev/codegen-ts/generators` — that subpath is deprecated and removed at 1.0.
87+
`meta init` and imported from `./codegen/generators/*` (ADR-0034) — 1.0 REMOVED their
88+
`@metaobjectsdev/codegen-ts/generators` export, so an owned copy is the only path. The
89+
engine primitives come from the package main entry, `@metaobjectsdev/codegen-ts`. The
90+
`/generators` subpath itself is NOT deprecated: it is the supported home of the generators
91+
with no ownable copy — `promptRender`, `outputParser`, `outputPrompt`, `extractor`,
92+
`renderHelper`, `traceHelperFile`, `routesFileHono`, `namesFile`, `callableFile`.
9093

9194
| Generator | Emits per entity |
9295
|---|---|

‎bun.lock‎

Lines changed: 18 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎docs/1.0-readiness.md‎

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,19 @@ Status legend: ✅ done · 🔶 in progress · ⬜ not started · ❓ **[RATIFY]
172172
- ⬜ **G1. Execute A1** (the decoupled cut): npm/PyPI/NuGet `→1.0.0`, Java/Kotlin
173173
`→8.0.0`, freeze the spec version at `Metamodel 1.0` (C4). Both forward; no
174174
backwards move on any registry.
175-
- ⬜ **G2. Remove the deprecated export** if A3=remove (one-time).
175+
- ✅ **G2. Remove the deprecated export** — DONE 2026-09-07. `entityFile` / `queriesFile` /
176+
`routesFile` / `barrel` are gone from `@metaobjectsdev/codegen-ts/generators`; owned copies
177+
(`meta init`, `meta eject <name>`) are the path, as `0.x-to-1.0.md` §11 already promised.
178+
179+
**Scoped by NAME, not by path — the checklist's own shorthand was wrong.** That subpath
180+
carries ~20 exports and only those four were deprecated; the rest (`promptRender`,
181+
`outputParser`, `outputPrompt`, `extractor`, `renderHelper`, `traceHelperFile`,
182+
`routesFileHono`, `namesFile`, `callableFile`) have **no other public import path**, and the
183+
CLI's own prompt-gate warning tells adopters to import `promptRender` from exactly there.
184+
Of six adopter estates surveyed before the cut, five import only non-deprecated names from
185+
that subpath and one imports the four: a path-wide removal breaks all six and the owned-copy
186+
remedy applies to one. A3's ratified intent and the published guide both name the four, so
187+
this is that decision implemented, not a narrowing of it.
176188
- 🔶 **G3. Scope declared, promise livable, publications current, RC exercised.**
177189
*(G3a/G3b/G3c done; **G3d is the one open gate** and it blocks G1.)*
178190

‎docs/features/migrations/0.x-to-1.0.md‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,10 +257,31 @@ Importing the built-in generators from `@metaobjectsdev/codegen-ts/generators`
257257
(`entityFile` / `queriesFile` / `routesFile` / `barrel`) is **removed** at 1.0.
258258

259259
- **Migration:** import the owned copies `meta init` scaffolds into
260-
`codegen/generators/*` and wire those in `metaobjects.config.ts`. See
260+
`codegen/generators/*` and wire those in `metaobjects.config.ts`. On an existing project,
261+
`meta eject entity` / `queries` / `routes` / `barrel` copies each one in place
262+
(`meta eject --list` names every ejectable generator). See
261263
[own-your-codegen](../own-your-codegen.md). (If you scaffolded with a recent
262264
`meta init`, you already import the owned copies — no change needed.)
263265

266+
- **The `@metaobjectsdev/codegen-ts/generators` subpath itself is unchanged.** Only those four
267+
names left it. It remains the supported home of the generators that have no ownable copy —
268+
`promptRender`, `outputParser`, `outputPrompt`, `extractor`, `renderHelper`,
269+
`traceHelperFile`, `routesFileHono`, `namesFile`, `callableFile`. If your config imports
270+
only those, **there is nothing to do here.** Check with:
271+
272+
```bash
273+
grep -rn '@metaobjectsdev/codegen-ts/generators' . \
274+
| grep -E 'entityFile|queriesFile|routesFile|barrel'
275+
```
276+
277+
No output means this section does not apply to you.
278+
279+
- **If you already own a `queries` generator, re-eject it.** Copies taken before 1.0 are
280+
missing the `@autoSet` branch — no `insertPreserving<Entity>` and no
281+
`<Entity>InsertPreservingSchema` import — so an entity with an `@autoSet` timestamp lost the
282+
#203 escape hatch silently. `meta eject queries` (over your copy, re-applying any
283+
customization) restores it.
284+
264285
## Additive in 1.0 (no migration required)
265286

266287
- **`field.uri` / `field.inet` subtypes + `@stringFormat`** (`email` / `hostname`)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// REFERENCE TEMPLATE — copy this into your repo (e.g. codegen/generators/barrel.ts) and own it.
2+
// Then import it LOCALLY in metaobjects.config.ts instead of from the package:
3+
// import { barrel } from "./codegen/generators/barrel.js";
4+
//
5+
// RUNTIME: this file executes under whatever runs `meta gen`, and the published CLI's
6+
// shebang is `#!/usr/bin/env node` — so it runs under NODE even in a Bun project. Do not
7+
// reach for `Bun.*` globals here; they are undefined and take the whole run down with
8+
// `Bun is not defined`. Use `node:` builtins instead.
9+
// targets: nothing framework-specific — it re-exports whatever the other generators
10+
// emitted. `extStyle` decides whether the re-export specifiers carry a
11+
// `.js` extension.
12+
// use-when: you want a single `index.ts` re-exporting every generated entity module.
13+
// emits: <target>/index.ts with one `export * from "./<Entity>"` per entity, alphabetical.
14+
// customize: the export form (star vs named), ordering, grouping by package, what to include/exclude.
15+
// composes-with: entity.ts (this re-exports the files entity.ts emits).
16+
//
17+
// Everything below imports ONLY from `@metaobjectsdev/codegen-ts` (the stable engine).
18+
// The composition (`renderBarrel`) is inlined here so you own it — change it freely.
19+
20+
import {
21+
oncePerRun,
22+
type Generator,
23+
type GeneratorFactory,
24+
type ExtStyle,
25+
type ResolvedTarget,
26+
barrelModuleSpecifier,
27+
formatTs,
28+
GENERATED_HEADER,
29+
} from "@metaobjectsdev/codegen-ts";
30+
31+
interface BarrelEntry {
32+
name: string;
33+
package: string | undefined;
34+
}
35+
36+
// --- composition (OWNED) — the barrel file body. Customize freely. ---
37+
function renderBarrel(
38+
entries: BarrelEntry[],
39+
extStyle: ExtStyle,
40+
selfTarget: ResolvedTarget,
41+
entityModuleTarget: ResolvedTarget,
42+
): string {
43+
const sorted = [...entries].sort((a, b) => a.name.localeCompare(b.name));
44+
const exports = sorted
45+
.map((e) => `export * from ${JSON.stringify(barrelModuleSpecifier(selfTarget, entityModuleTarget, e.package, e.name, extStyle))};`)
46+
.join("\n");
47+
return `// ${GENERATED_HEADER} — DO NOT EDIT.\n${exports}\n`;
48+
}
49+
50+
export interface BarrelOpts {
51+
target?: string;
52+
}
53+
54+
export const barrel = function barrel(opts?: BarrelOpts): Generator {
55+
const generator: Generator = {
56+
name: "barrel",
57+
generate: oncePerRun(async (entities, ctx) => ({
58+
path: "index.ts",
59+
content: await formatTs(
60+
renderBarrel(
61+
entities.map((e) => ({ name: ctx.renderContext!.valueObjectEmittedName(e), package: e.package })),
62+
ctx.renderContext!.extStyle,
63+
ctx.renderContext!.selfTarget,
64+
ctx.renderContext!.entityModuleTarget,
65+
),
66+
),
67+
})),
68+
};
69+
if (opts?.target) {
70+
generator.target = opts.target;
71+
}
72+
return generator;
73+
} as GeneratorFactory<BarrelOpts>;

0 commit comments

Comments
 (0)