Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
a826ed3
fix: close the 1.1.0 skill, migration-guide, CLI and prerelease gaps …
dmealing Oct 14, 2026
3d59795
test(sdk): the repository's name in its public URL is not the metadat…
dmealing Oct 14, 2026
4494ada
fix(maven-plugin): the requires refusal says 'them' when several gene…
dmealing Oct 14, 2026
9d0787a
fix(prerelease): repin a metaobjects plugin's own version wherever it…
dmealing Oct 14, 2026
a48510d
refactor: one migration-guide constant in C#, one build-metadata stri…
dmealing Oct 15, 2026
52de926
no-mistakes(review): Fix shipped pom requires, owned list entries, sp…
dmealing Oct 15, 2026
9724dd8
fix(prerelease): leave a module's inherited ${metaobjects.version} re…
dmealing Oct 15, 2026
a912bdc
spec: ADR-0058, one physical-naming setting read by every port, and i…
dmealing Oct 15, 2026
fa1a6e8
feat(naming): one physical-naming setting in TypeScript, the migratio…
dmealing Oct 15, 2026
e4116e7
feat(naming): C# reads the one physical-naming setting (ADR-0058)
dmealing Oct 15, 2026
fc7d5d1
test(integration): the TypeScript generated-route lanes declare the n…
dmealing Oct 15, 2026
cf65908
feat(naming): Python reads the one physical-naming setting (ADR-0058)
dmealing Oct 15, 2026
0947029
feat(naming): Java and Kotlin read the one physical-naming setting (A…
dmealing Oct 15, 2026
233f5f4
docs(recipes): MySQL recipe matches its shipped skill copy
dmealing Oct 15, 2026
6288a33
test(cube): the live cube lanes take literal columns from the corpus …
dmealing Oct 15, 2026
8f4104e
no-mistakes(review): Resolve Maven naming config upward; fix review f…
dmealing Oct 15, 2026
d313c85
no-mistakes(review): Walk up for C# naming config; fix round-2 findings
dmealing Oct 15, 2026
77d1e6e
no-mistakes(review): Fix eject list entries, staleness ordering, nami…
dmealing Oct 15, 2026
d744467
docs(metamodel): @column and @table descriptions name the naming setting
dmealing Oct 15, 2026
1e2a91e
fix(verify): the codegen naming probe also tries the other table rule
dmealing Oct 15, 2026
6f70fcc
fix(verify): the C# naming probe regenerates from a fresh load per ca…
dmealing Oct 17, 2026
d74f3b8
no-mistakes(review): Make prerelease steps signal-safe; fix repin mes…
dmealing Oct 17, 2026
3b49aae
no-mistakes(document): Refresh stale naming comment in codegen-ts config
dmealing Oct 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .claude/rules/codegen-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ origins live on `object.projection` only.
Gated end-to-end by `fixtures/api-contract-conformance/projection/` (view-only)
and `.../write-through/` (table + replica view).

**`columnNamingStrategy`** in `metaobjects.config.ts`: `snake_case` (default) | `literal` | `kebab-case`.
**Column and table naming** is `naming` in `.metaobjects/config.json` (ADR-0058), read by every port: `columns` `snake_case` (default) | `literal` | `kebab-case`, `tables` `snake_case` (default) | `literal`. Generators read it as `ctx.columnNamingStrategy` (set from the loaded root); `metaobjects.config.ts` no longer takes it.

### Currency (Project F)

Expand Down
70 changes: 69 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,74 @@ here.**

## [Unreleased]

### Changed — one physical-naming setting, read by every port (ADR-0058)

**This changes generated column names in C#, Java, Kotlin's runtime and Python unless you add
one line.** Column and table names that the metadata does not give (`@column`, `@table`,
`@view`, a source's `name`) now come from one project setting, `naming` in
`.metaobjects/config.json`:
`{ "naming": { "columns": "snake_case" | "literal" | "kebab-case", "tables": "snake_case" | "literal" } }`.
`meta migrate`, every port's codegen (the names generators included), every runtime
`ObjectManager` and `verify` read it from the loaded model, so codegen and the runtime can
no longer disagree. Both rules default to `snake_case` in every port, which is what
`meta migrate` creates; C#, Java, the JVM runtime and Python defaulted to `literal`. A
database whose columns are named exactly like the fields adds
`"naming": { "columns": "literal" }`. Every former place to set the rule is refused with a
message naming the setting and the guide, never silently ignored: `columnNamingStrategy` in
`metaobjects.config.ts` and on `ObjectManager` and `agentDocsFile()` (TypeScript),
`--column-naming` (C#, Python), the `columnNaming` generator arg in `pom.xml` and
`SimpleMappingHandlerDB.setColumnNaming` (Java, Kotlin), `ObjectManager(column_naming=)`
(Python). The engine options that carried the rule (`buildExpectedSchema`,
`buildProjectionViews`, `buildReportViews`, `computeDrift`, `planOffline`,
`baselineFromMetadata`) read it from the model instead. Table names gain a `literal` rule.
Every port runs the shared `fixtures/naming-conformance/physical-names/` corpus.
Migration: `docs/features/migrations/physical-naming.md`.

Found by the application-building test of 1.1.0-rc.3: following the migration guide, a plain
`metaobjects gen` rewrote every `*_names.py` with camelCase column names the snake_case
database does not have.

### Added

- **Python: `templates` in `metaobjects.config.yaml`.** The template directory was a flag
only; `gen`, `verify --codegen` and `verify --templates` read the key, and a `--templates`
that contradicts it is refused.
- **Maven: `requires` is checked.** `mvn metaobjects:generate` fails, naming the missing
companion and its class, when a listed generator's output references what an unlisted one
writes (a Spring controller without the DTO, repository and filter allowlist; a Kotlin
controller without the Exposed tables, filter allowlists and relation queries), where it
used to exit 0 and leave the build to fail in `javac` or `kotlinc`.
`<allowUnmetRequires>true</allowUnmetRequires>` runs such a list when the files are
supplied another way. Every Java and Kotlin `requires` closure, and the skills' pom
examples, are compiled over the fitness corpus in a test.

### Fixed
- `verify --codegen` (Python, C#) says when the committed output was generated with another
column rule, another table rule, or both, and names the `naming` setting that reproduces it,
instead of advising a regeneration that would commit the wrong column or table names.
- Every "removed in 1.1.0" message and skill reference names the migration guide by its full
public URL; the repository path they printed exists in no installed package.
- The Java and Kotlin skills' only `pom.xml` examples generated code that did not compile;
each now lists the whole REST tier, and the Kotlin skill lists the runtime dependencies the
generated code needs and that the controller needs `KotlinRelationsGenerator`.
- The migration guide and the skills give each port's documentation its own directory: in a
shared one, every port's `verify --codegen` reported the other ports' pages as drift.
- `dotnet meta gen --list` prints the expression that lists each generator in
`codegen/Generators.cs` (`new MetaObjects.Codegen.Generators.RenderHelperGenerator("prompts")`)
and its options.
- The C# "agent context is stale" notice no longer fires on build metadata alone
(`1.1.0-rc.3` against `1.1.0-rc.3+<sha>`).
- `meta verify --docs` prints its removal line once, as plain text.
- `metaobjects verify --templates` reads `metadata` and `templates` from
`metaobjects.config.yaml` instead of refusing the config.
- The skills no longer say metadata lives under `metaobjects/` (it is the default only), and
name C#'s positional `<metadataDir>` (there is no `--metadata-dir`).
- Pre-release tooling: `prerelease:publish` reads what is released from public npm and the
release tags, not `package.json`, so a cut during release preparation is not numbered one
minor too high, and it refuses a `--base` that skips an unpublished CHANGELOG section; the
iteration counter reads every page of the registry listing; a SIGTERM restores the version
files. `prerelease-link.sh` links and repins every Maven and Python project at any depth and
repins the .NET local tool manifest.

- A generated documentation page that no current object produces (for example the
`<Object>.md` page of an object that was removed) is reported as drift. 1.0's
Expand Down Expand Up @@ -1187,7 +1254,8 @@ until you regenerate.
ADR-0034 Amendment 9.
- `meta docs` prints `` `meta docs` was removed in 1.1.0. `meta gen` writes documentation
now: declare each docs generator in `generators` in metaobjects.config.ts. See
docs/features/migrations/docs-are-generators.md, section "TypeScript". `` and exits 2.
https://github.com/metaobjectsdev/metaobjects/blob/main/docs/features/migrations/docs-are-generators.md,
section "TypeScript". `` and exits 2.
`meta verify --docs` prints the same shape, naming `meta verify --codegen`, and exits 2.
- A config with a `docs` key fails `meta gen` and `meta verify --codegen` before anything
is written, naming the block and the migration section. A project with no
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,10 @@ to nothing, and does not check that each claimed node complies).
non-`table` source-kind / flattened-object codegen is partial). **C#** has no
ObjectManager runtime tier (EF Core *is* the runtime) — hand services over the generated
`DbContext` are expected.
- **Single-source config** — `apiPrefix` (URL prefix wired into routes + hooks) and
`columnNamingStrategy` (snake_case / literal / kebab-case) and per-target output dirs:
hunt these values hard-coded in multiple places instead of resolved from config.
- **Single-source config** — `apiPrefix` (URL prefix wired into routes + hooks), the
`naming` block of `.metaobjects/config.json` (column and table rules, read by every port)
and per-target output dirs: hunt these values hard-coded in multiple places instead of
resolved from config.
- **CALIBRATION — planned, not yet shipped:** the declared-API surface (`api.base`,
`api.operational`, `operation.query`, `operation.command`, `binding.rest`) and MCP exposure
of declared prompts/tools are **not yet in the registry** — their absence is not an adopter
Expand Down
6 changes: 4 additions & 2 deletions agent-context/skills/metaobjects-authoring/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ that drive code generation, runtime behavior, and drift detection. You author it
the loader reads it, the codegen emits idiomatic per-language code from it. This
skill is the procedure for writing it correctly.

Metadata lives in files under `metaobjects/` at project root, one file per domain
Metadata lives in files under the project's metadata directory (`metaobjects/` unless
the project's configuration names another: `sources` in `.metaobjects/config.json`, or the
port's own setting), one file per domain
concept (`meta.commerce.json`, `meta.users.yaml`, …). Each file declares a
`package` on its root node. Files in the same `package` with the same object
`name` are merged by the loader.
Expand Down Expand Up @@ -450,7 +452,7 @@ immutable. Supported in all five ports; the worked example is in `references/inh

## Requirements — capability ledger (opt-in)

**This capability exists whether or not the project uses it yet.** `requirement.functional` and `requirement.architectural` are registered metadata types, declared in `metaobjects/` beside the entities they describe and loaded by the same loader — no side file, no bespoke parser. They record *why* each part of the model exists, so a field with no reason to exist becomes visible as one.
**This capability exists whether or not the project uses it yet.** `requirement.functional` and `requirement.architectural` are registered metadata types, declared in the metadata directory beside the entities they describe and loaded by the same loader — no side file, no bespoke parser. They record *why* each part of the model exists, so a field with no reason to exist becomes visible as one.

Reach for it when the project needs to answer any of:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Requirements — `requirement.functional` / `requirement.architectural`

Capabilities are **metadata**, declared in `metaobjects/` beside the entities they
Capabilities are **metadata**, declared in the metadata directory beside the entities they
describe. Read the existing requirement nodes before designing anything. Two rules matter
more than the rest.

Expand Down
5 changes: 4 additions & 1 deletion agent-context/skills/metaobjects-codegen/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ systems — and have it import the generated types.

You run a `gen` step. The runner:

1. Loads all metadata under `metaobjects/` (the same loader the runtime uses).
1. Loads the project's metadata from wherever its configuration points (the same loader
the runtime uses): `sources` in `.metaobjects/config.json` (TypeScript, and C# when gen
names no `<metadataDir>`), `metadata` in `metaobjects.config.yaml` (Python), the
plugin's `<loader><sourceDir>` (Java, Kotlin). `metaobjects/` is only the default.
2. Resolves output targets and precomputes shared render state.
3. Runs each configured **generator** — most emit one file per entity; some emit a
single shared file (a barrel, a DB-context, an app-config).
Expand Down
Loading
Loading