Skip to content

Commit bc15ee4

Browse files
dmealingclaude
andcommitted
docs(changelog): 0.24.1 records the adopter batch — #339, #340, #341, #343 + the drizzle floor
Five entries beside the #342 one already in the section. Each states what an adopter observed, not what changed internally, since every one of these fails in a way the project's own suite could not see: #339 — `meta upgrade` skipped a 161-file YAML estate and called it clean #340 — a sub-project's generated tree went 376 files → 831 #341 — TS1484 on generated code under `verbatimModuleSyntax` drizzle — generated SQLite did not compile on two minors the peer range admitted #343 — the AI-facing index taught vocabulary 0.24.0 removed The recurring note across four of them is the same, and it is recorded rather than summarised away: the gate that should have caught each one either did not exist or had a fixture that could not express the failing case. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DhpswkF1NvwxhFWMmdAT15
1 parent 08b68c1 commit bc15ee4

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,126 @@ same blindness that let the original defect ship. `migrate-ts`'s `loadFixture` n
9090
loader errors instead of discarding them — a checked-in fixture had been declaring the
9191
illegal form and driving those suites green. All five ports green.
9292

93+
### Fixed — `meta upgrade` rewrote nothing on a YAML estate, then called it clean ([#339](https://github.com/metaobjectsdev/metaobjects/issues/339))
94+
95+
`meta upgrade` is the fixer for everything `0.24.0` retired. On a **YAML** estate it
96+
rewrote nothing, skipped every file, and finished with `no retired vocabulary found in
97+
the JSON metadata` — while **405 retired constructs** sat in those files (321 ×
98+
`violation:` alone, every one a mechanical single-token rename). The skip notice printed
99+
first, but as the header of a 161-line file list, so the line that stuck said the
100+
opposite of the truth. It also exited **1**, giving a script no way to tell "nothing to
101+
do" from "could not look". YAML is first-class authoring (ADR-0006), so for these
102+
adopters the tooling for a breaking change was a no-op and the whole migration manual.
103+
104+
**YAML is now rewritten.** The arm lives in its own module behind its own package
105+
subpath, dynamic-imported by the CLI, because `vocabulary-rewrite.ts` is reachable from
106+
`metadata`'s root entry and may not import the Node-only `yaml` package — the same split,
107+
for the same reason, as `yaml-positions.ts` / `yaml-positions-walker.ts`.
108+
109+
It is **parser-driven** where the JSON arm is regex-driven, and that is the whole
110+
difference: a hand-rolled YAML mode was tried in the JSON arm first and withdrawn after
111+
it corrupted files — a multi-item block sequence lost every item but the first, and the
112+
dominant authoring style (flow mappings, `{ name: x, readOnly: true }`) was not matched
113+
at all, so the rename silently did nothing. Both are the same failure, because YAML's
114+
value extent is not derivable by scanning. Asking the parser for each span makes a
115+
four-line block sequence and a one-line flow mapping stop being special cases. It stays
116+
**surgical, not parse-and-reprint** — spans are located by the parse and replaced in the
117+
original text, so comments, key order and quoting survive byte-for-byte, and
118+
`doc.toString()` never reflows an adopter's file.
119+
120+
Reporting and exit codes, which were the other half of the report:
121+
122+
- every conclusion now names how many files it is a conclusion **about**, so a bare
123+
"not found" can no longer stand in for "nothing was examined";
124+
- a file that does not **parse** is reported as NOT checked rather than counted clean —
125+
the same defect arriving by a different route;
126+
- **exit 3** now means "some files could not be read", leaving `1` for "refusals remain",
127+
`2` for bad usage and `0` for genuinely clean.
128+
129+
Gated end-to-end through the built binary and by unit cases covering both authoring
130+
styles, the multi-item sequence, flow-mapping comma handling, scope discipline,
131+
idempotence and an unparseable file. The load gate asserts the rewritten output **loads
132+
clean** after first proving the input fails, so it cannot pass vacuously.
133+
134+
### Fixed — a sub-project's generated tree absorbed unrelated metadata ([#340](https://github.com/metaobjectsdev/metaobjects/issues/340))
135+
136+
The gen-side remainder of #326/#327. Once source resolution learned to walk upward,
137+
`meta gen` in a package whose `metaobjects.config.ts` sits below the collection root
138+
loaded the **ancestor's entire source set**: one adopter's web app went from **376
139+
generated files to 831**, the surplus being another module's server-side prompt payload
140+
DTOs — absent from the app's own metadata directory entirely. It fails **open** (`tsc`
141+
passes, tests pass), so the only symptom is a generated tree that quietly doubled.
142+
143+
The rule is #326's own principle carried to its other half: **an ancestor
144+
`.metaobjects/config.json` is the DEFAULT for a package that declares no sources, never
145+
an ADDITION to one that does.** It can only ever narrow, and only where the shape could
146+
not have worked before — when the two configs sit together (every `meta init` project)
147+
the original collection is returned untouched, and a package that declares no sources of
148+
its own still inherits the ancestor, which is #326's shape and is gated as its own arm.
149+
150+
`verify --codegen` gets the same treatment, and that is not optional: it regenerates and
151+
diffs against committed output, so narrowing `gen` alone would make every sub-project
152+
report the ancestor's whole contribution as drift. `.metaobjects/` **state** — migrations,
153+
snapshots, the operational block — stays keyed on the discovered collection's directory,
154+
which #326 settled; this narrows what is LOADED, not where state lives.
155+
156+
### Fixed — generated enum types were value imports (TS1484) ([#341](https://github.com/metaobjectsdev/metaobjects/issues/341))
157+
158+
A materialized shared `field.enum` exports two symbols from one module — the TS type `E`
159+
and the Zod value `EEnum`. The value-object emitter imported the type by bare name, so
160+
both merged into a single value import:
161+
162+
```ts
163+
import { DispositionEnum, DispositionEnumEnum } from "./enums"; // TS1484
164+
```
165+
166+
Under `verbatimModuleSyntax: true` — the default in current Vite/TS templates — that is a
167+
hard error on generated code the adopter cannot edit. A regression against `0.23.1`, and
168+
invisible to any project that has not enabled the flag, which is why it shipped.
169+
170+
The regression gate for this class (#165) already existed and already compiled real
171+
output under that exact flag. It missed this because its fixture had no enum — and fixing
172+
it needed the right **shape**, not just an enum: an entity types its enum column through
173+
Drizzle's `InferSelectModel` and only ever imports the Zod const (correctly a value), so
174+
an entity fixture compiles clean with the bug fully present. A **value object** declares
175+
an explicit interface member and imports the type by name, which is where the defect
176+
lives and where the adopter hit it.
177+
178+
### Fixed — generated SQLite did not compile on two minors the peer range admitted
179+
180+
Generated table calls pass `extraConfig` in Drizzle's **array** form. `pgTable` has
181+
accepted that since `0.36.0`, but `sqliteTable` only since **`0.38.0`** — below it the
182+
only overloads take the legacy `SQLiteTableExtraConfig` Record, so generated SQLite fails
183+
to type-check (`Type 'CheckBuilder[]' is not assignable to type 'SQLiteTableExtraConfig'`).
184+
The peer range was `>=0.36.0 <1.0.0`, so it admitted two minors on which our own output
185+
does not compile — the same class as the `0.21.5` peer-range work: a compatibility the
186+
package promised and never had. Floored at `0.38.0`; Postgres is unaffected.
187+
188+
This reached no gate because nothing compiled a SQLite table that passed `extraConfig` at
189+
all — the compile gate's entity had a single-column inline primary key and no enum, index
190+
or table-level constraint, the one shape that avoids that argument entirely. The fixture
191+
now carries an enum, whose CHECK travels the same code path every other `extraConfig`
192+
source uses, and the devDependency moves in lockstep so the suite type-checks generated
193+
output **at** the declared floor rather than above it.
194+
195+
### Fixed — the AI-facing docs taught vocabulary this release removed ([#343](https://github.com/metaobjectsdev/metaobjects/issues/343))
196+
197+
`docs/llms/{llms.txt,llms-full.txt}` — the entry point `metaobjects.dev` serves to
198+
assistants — still taught `@verifiedBy` as live and gave `@status` as the pre-`0.24.0`
199+
four-value enum. Both now fail the load, so an assistant scaffolding from the published
200+
index produced a ledger that **cannot load**. Corrected to `planned | live | partial`,
201+
with the retirements named AS retirements (pointing at `meta upgrade`) rather than
202+
deleted silently — a reader arriving with a `0.23.x` ledger needs to be told what
203+
happened to it. The other three `0.24.0` retirements appear in neither file, so the drift
204+
was confined to the requirement paragraph.
205+
206+
This is the **third** instance of one family (#337, #342, #343): shipped documentation
207+
teaching metadata the loader rejects, each found by an adopter or a review rather than by
208+
a gate, each fixed by hand in a different file. The durable fix these keep pointing at —
209+
extracting the authored examples from shipped docs, skills and fixtures and loading them
210+
under a strict loader — is tracked separately; `meta upgrade`'s retirement map is already
211+
the natural source of truth for "what must no longer appear in an example".
212+
93213
## [0.24.0] — npm `0.24.0` · PyPI `0.24.0` · NuGet `0.24.0` · Maven `7.24.0`
94214

95215
> ### ⚠️ BREAKING FOR METADATA AUTHORS — five vocabulary changes in ONE window

0 commit comments

Comments
 (0)