diff --git a/CHANGELOG.md b/CHANGELOG.md index dd2fa9c49..39e77df87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,27 @@ here.** [docs/features/api-contract.md](docs/features/api-contract.md#report-export) and [ADR-0031 Amendment 1](spec/decisions/ADR-0031-serialization-vs-data-download-boundary.md). +### Changed + +- **A bare `verify` runs the same default gate set in every port: codegen drift, prompt + templates and the requirement ledger.** Until now a bare run covered one gate: `meta verify` + and `dotnet meta verify` ran only templates, so "run `verify` in CI" did not catch generated + code that had fallen behind the model; `metaobjects verify` and `mvn metaobjects:verify` ran + only codegen, so prompt drift passed. `--db`, `--deps` and `--replay` stay opt-in, and naming a + subverb still runs only the gates named. A gate the run has no configuration for is skipped + with a one-line note instead of failing: `meta verify` without a `metaobjects.config.ts` (a config that exists but fails to load exits 2), + `metaobjects verify` with no `metaobjects.config.yaml` and no `--prompts`, `dotnet meta verify` + without `--out ` and `codegen/Generators.cs` (C# has no config-resolved output directory: + pass `--out ` in CI to get the codegen gate), `mvn metaobjects:verify` without + `-Dmeta.verify.templateRoot`. Pinned per port by tests that run a bare verify over drifted + input. **Behaviour change:** a CI step that ran a bare `verify` and relied on the narrower + default can now go red where it was green, because the gate it never ran now runs. Node + `meta` and C# gain the codegen gate (stale generated output fails), Python and Java/Kotlin + gain the template gate (prompt drift fails, when a template root is configured). To keep the + old scope, name the gate: `meta verify --templates`, `dotnet meta verify --templates`, + `metaobjects verify --codegen`, `mvn metaobjects:verify -Dmeta.verify.mode=codegen`. The Maven + `meta.verify.mode` parameter no longer defaults to `codegen`; unset means both gates. + ### Fixed - **A failed `meta deps sync` no longer leaves a lock and snapshot that cannot load.** The @@ -49,6 +70,9 @@ here.** ### Documentation +- **Two doc errors corrected against the code.** `docs/recipes/mysql.md` said Python ships a + Postgres driver only; it ships SQLite and MySQL drivers beside it. `docs/features/api-contract.md` + said only TypeScript enforces the `in`-list cap of 100; every port does. - **The fit-assessment prompt's capability sheet is re-checked against 1.1.4 / Maven 8.1.4** (it read 1.0.8, last checked 2026-09-26): reporting, the requirements gate and `--require-implementers`, the `wire` setting and eject in every port are now listed. The hosted diff --git a/agent-context/skills/metaobjects-audit/references/typescript.md b/agent-context/skills/metaobjects-audit/references/typescript.md index 8c8df4696..d4b42126a 100644 --- a/agent-context/skills/metaobjects-audit/references/typescript.md +++ b/agent-context/skills/metaobjects-audit/references/typescript.md @@ -41,7 +41,7 @@ meta gen # render → 3-way merge → write (overwrites @ meta gen --dry-run # preview without writing meta gen Author Post # scope to named entities meta verify --codegen # regenerate to temp, diff vs committed output -meta verify --templates # check {{field}} refs vs payload VO (bare `meta verify` default) +meta verify --templates # check {{field}} refs vs payload VO (a bare `meta verify` runs this and `--codegen`) meta verify --db # schema drift — live DB vs metadata (requires DB connection) meta verify --codegen --templates --db # all three drift checks in one pass ``` diff --git a/agent-context/skills/metaobjects-codegen/references/csharp.md b/agent-context/skills/metaobjects-codegen/references/csharp.md index 32395566e..6b20b40ef 100644 --- a/agent-context/skills/metaobjects-codegen/references/csharp.md +++ b/agent-context/skills/metaobjects-codegen/references/csharp.md @@ -89,8 +89,9 @@ in, and C# ejects land in its `codegen/generators/` beside the `.ts` copies. The `Codegen.csproj` compiles only `*.cs` and `tsconfig.codegen.json` only `*.ts`. Ignore the build output (`codegen/bin/`, `codegen/obj/`) in `.gitignore`. -`dotnet meta verify` defaults to `--templates` (the FR-004 prompt/template drift -gate, see the prompts reference); `--codegen` is the codegen-output drift gate. +A bare `dotnet meta verify` runs `--templates` (the FR-004 prompt/template drift +gate, see the prompts reference) and `--codegen` (the codegen-output drift gate; +skipped with a note unless `--out ` and `codegen/Generators.cs` are present). **Schema migration + live-DB drift are NOT `dotnet meta`** — they run through the Node `meta` tool (see the migration reference). diff --git a/agent-context/skills/metaobjects-fit-assessment/references/capability-sheet.md b/agent-context/skills/metaobjects-fit-assessment/references/capability-sheet.md index 0edfb382b..2f6547716 100644 --- a/agent-context/skills/metaobjects-fit-assessment/references/capability-sheet.md +++ b/agent-context/skills/metaobjects-fit-assessment/references/capability-sheet.md @@ -27,8 +27,8 @@ building block. Every generator is a reference helper an adopter selects, ejects (`server/typescript/packages/codegen-ts/src/db-emitting.ts`). - **The drift gate per port** — regenerate into a temp tree and diff: `meta verify --codegen` (TS); `mvn metaobjects:verify` (Java/Kotlin; `codegen` is the default mode); `dotnet meta - verify --codegen` (C#; bare `verify` means `--templates` there); `metaobjects verify` (Python; - `--codegen` is the default). Source: `docs/features/cli.md`. + verify --codegen` (C#; bare `verify` runs it when `--out` and `codegen/Generators.cs` are present); + `metaobjects verify` (Python; `--codegen` is part of the default). Source: `docs/features/cli.md`. - **Generated code compiles**: a codegen-compile gate compiles every port's emitted model tier with its real compiler in CI (`docs/CONFORMANCE.md`, "Split coverage"). - **Sharing a model** (`docs/features/metadata-dependencies.md`): in one repository, every port diff --git a/agent-context/skills/metaobjects-verify/SKILL.md b/agent-context/skills/metaobjects-verify/SKILL.md index bfaf94355..54ffb4673 100644 --- a/agent-context/skills/metaobjects-verify/SKILL.md +++ b/agent-context/skills/metaobjects-verify/SKILL.md @@ -92,15 +92,16 @@ JSON. A pass that did not run reports `status: "skipped"` and why, so an empty l always means "found nothing", never "never looked"; what the payload does not carry is named in its own `notRepresented[]`. -**A bare `verify` is a partial check, not the full gate.** The Node/C# default runs -only `--templates`; Java/Python's bare default runs only `--codegen` — either way, -paired with the advisory anti-pattern pass above, never all three subverbs. Treat a -bare run as a smoke test: the real done-check is running the subverbs your project -uses explicitly — `verify --codegen`, and, where a DB exists, `verify --db `. -The Node `meta verify` ends every run, bare or not, with a `not run:` line naming -each gate it skipped and the flag that selects it; on a model with no templates a -bare run checks nothing but the requirement ledger and still exits 0, so never -wire a bare `meta verify` into CI as the whole gate. +**A bare `verify` runs the code gates, not the database gate.** In every port a bare +run covers codegen drift (stale generated code), prompt-template drift and the +requirement ledger, paired with the advisory anti-pattern pass above. `verify --db +`, `--deps` and `--replay` stay opt-in (`--db` is Node `meta` only). A bare run +skips a gate it has no configuration for and says so in one line: Node `meta` with +no `metaobjects.config.ts`, Python with no `metaobjects.config.yaml`, `dotnet meta` +with no `--out ` or `codegen/Generators.cs`, Maven with no `templateRoot`. The +Node `meta verify` ends every run, bare or not, with a `not run:` line naming each +gate it skipped and the flag that selects it; read it, because a skipped gate is a +gate that did not guard the build. ## Requirements are checked on every run diff --git a/docs/features/api-contract.md b/docs/features/api-contract.md index 75422eb20..91cbcf3fe 100644 --- a/docs/features/api-contract.md +++ b/docs/features/api-contract.md @@ -197,9 +197,10 @@ ports accept leading wildcards, which is exactly why it is listed here as a TS-only extension). The **`in`-list size cap** (reject an `in` list longer than 100 → HTTP 400) is a -safety limit, not a feature — TS enforces it, the other ports currently do not. -Unifying that cap cross-port is the one item here worth doing regardless of -feature demand (it is a consistency/safety divergence, not a capability). +safety limit, not a feature, and every port enforces it: TypeScript +(`DEFAULT_MAX_IN_LIST` in the `runtime-ts` filter parser), Python (`MAX_IN_LIST`), +Java (`FilterParser.MAX_IN_LIST`), C# (`FilterParser.MaxInList`) and Kotlin (a generated +file-private constant that matches the TypeScript default). ### TS-only error responses (not part of the cross-port contract) diff --git a/docs/features/cli.md b/docs/features/cli.md index 2ee3965e0..963644148 100644 --- a/docs/features/cli.md +++ b/docs/features/cli.md @@ -30,15 +30,15 @@ command surface splits in two: | **Schema migrate** | **Node `meta`** | `meta migrate` | **any backend** — schema is Node-only (ADR-0015) | | **Schema drift** (`verify --db`) | **Node `meta`** | `meta verify --db` | **any backend** — live-DB drift, Node-only | | **Codegen drift** (`verify --codegen`) | **Node `meta`** | `meta verify --codegen` | TS reference (ADR-0021 D2) — regen-to-temp + diff committed output | -| **Template/prompt drift** (`verify --templates`) | **Node `meta`** | `meta verify --templates` | TS reference (ADR-0021 D2) — `{{field}}`↔payload; the bare-`verify` default | +| **Template/prompt drift** (`verify --templates`) | **Node `meta`** | `meta verify --templates` | TS reference (ADR-0021 D2) — `{{field}}`↔payload; part of the bare-`verify` default | | **Vocabulary upgrade** (`upgrade`) | **Node `meta`** | `meta upgrade [--to ] [--apply]` | **any backend** — rewrites RETIRED metadata vocabulary (`@violation` → `@counterexample`, `@readOnly` → `@mutability`, dropping `@verifiedBy`) and resolves ATTRIBUTE CONTRADICTIONS (`@fields` beside `@expr` on an index key). Node-only because it edits the metadata documents themselves, which every port shares; a non-TS project runs `npx meta upgrade` against its own `metaobjects/`. **Canonical JSON and YAML alike.** Previews by default. Retirements needing a human decision are refused and the run exits non-zero, so CI cannot record a partial migration as finished | | **Vocabulary search** (`types`) | **Node `meta`** | `meta types [query]` | **any backend** — apropos/`kubectl explain` over the live metamodel registry (names + descriptions + when-to-use); the vocabulary is cross-port identical (registry-conformance) | | **Dependency sync** (`deps`) | **Node `meta`** | `meta deps sync \| check \| list` | **any backend** — resolves a declared metadata dependency's `path` transport into a committed snapshot + lock (FR-023), so `sync`/`check`/`list` themselves stay Node-only regardless of your server language. TypeScript and Python then LOAD that snapshot at every rung of their own source ladder — the two ports that implement dependency resolution in Phase 1a; Java, Kotlin, and C# don't read `dependencies` yet (Phase 2). See [`metadata-dependencies.md`](metadata-dependencies.md) | | **Canonical format** (`fmt`) | every port | `meta fmt` / `dotnet meta fmt` / `mvn metaobjects:fmt` / `metaobjects fmt` | (#304) ships in **every** port — the canonical serializer already exists in all five, so formatting is local, not Node-only. `--check` lists non-canonical files and exits non-zero without changing anything. Formats each file STANDALONE — own-mode, declared-here layer only (ADR-0039); an `extends` onto another file's base is preserved as-is, never resolved or erred on; a file declaring `overlay: true` anywhere — whether or not a same-file base exists — is reported as skipped rather than merged (merging would drop the overlay marker, a structural change fmt never makes). A YAML file is always skipped — no canonical YAML emitter exists (ADR-0006). Before writing, every port reloads the whole project with the candidate swapped in and refuses the write unless the reloaded model's canonical form is byte-identical to the untouched baseline — fmt never changes meaning. See [Fixture corpus](#meta-fmt--canonical-formatting-304) below and `fixtures/fmt-conformance/README.md` | | TS codegen | Node `meta` | `meta gen` | TS projects. **No `--template-spec` flag, deliberately** — `metaobjects.config.ts` already takes generator VALUES, so a declarative template generator is declared there (`templateGenerator()`, or `templateSpecToGenerators(parseTemplateSpec(spec))` to reuse a C#/Python spec file). Keeping it in the config is what lets `meta verify --codegen` regenerate WITH it, since that gate re-runs the config's generator list; see [declarative template scopes](codegen-concepts.md#declarative-template-scopes) | -| C# codegen | `dotnet meta` | `dotnet meta init` / `gen` / `verify --templates` / `verify --codegen` | a .NET tool (`ToolCommandName=dotnet-meta`); invoked `dotnet meta` so it never shadows the Node `meta`; ships the ADR-0021 D2 subverbs (`--db` rejected, exit 2; bare `verify` = `--templates`). **The generator list is `codegen/Generators.cs`** (ADR-0034 Amendment 9): `dotnet meta init` writes it with `codegen/Program.cs` (two lines that run it) and `codegen/Codegen.csproj`, and `gen` / `verify --codegen` always run it through `dotnet run --project codegen`. With no `codegen/Generators.cs` they exit 2 and write nothing; `--generators` only narrows the list to declared entries. Every entry may set its own output directory (`ApiDocsGenerator { OutDir = ... }`), and `verify --codegen` compares each one. A declarative Mustache template-spec (the cross-port JSON contract shared with Python) is one more entry, `TemplateSpecGenerator { Spec = "", TemplateRoot = "" }`; `gen` no longer reads `--template-spec` or a project-root `template-spec.json`, and a run that finds either with no such entry fails before writing anything; see [declarative template scopes](codegen-concepts.md#declarative-template-scopes). `dotnet meta docs` was removed in 1.1.0: it prints the line that points at [the migration section](migrations/docs-are-generators.md#c) and exits 2 | +| C# codegen | `dotnet meta` | `dotnet meta init` / `gen` / `verify --templates` / `verify --codegen` | a .NET tool (`ToolCommandName=dotnet-meta`); invoked `dotnet meta` so it never shadows the Node `meta`; ships the ADR-0021 D2 subverbs (`--db` rejected, exit 2; bare `verify` = `--templates` plus `--codegen` when `--out` and `codegen/Generators.cs` are present). **The generator list is `codegen/Generators.cs`** (ADR-0034 Amendment 9): `dotnet meta init` writes it with `codegen/Program.cs` (two lines that run it) and `codegen/Codegen.csproj`, and `gen` / `verify --codegen` always run it through `dotnet run --project codegen`. With no `codegen/Generators.cs` they exit 2 and write nothing; `--generators` only narrows the list to declared entries. Every entry may set its own output directory (`ApiDocsGenerator { OutDir = ... }`), and `verify --codegen` compares each one. A declarative Mustache template-spec (the cross-port JSON contract shared with Python) is one more entry, `TemplateSpecGenerator { Spec = "", TemplateRoot = "" }`; `gen` no longer reads `--template-spec` or a project-root `template-spec.json`, and a run that finds either with no such entry fails before writing anything; see [declarative template scopes](codegen-concepts.md#declarative-template-scopes). `dotnet meta docs` was removed in 1.1.0: it prints the line that points at [the migration section](migrations/docs-are-generators.md#c) and exits 2 | | Java/Kotlin codegen | Maven plugin | `mvn metaobjects:generate` (`metaobjects:generate`) | Kotlin generators run through the same goal — see below. **No `--template-spec` flag, deliberately** — `` already loads a consumer class from the project classpath, so the declarative surface is `com.metaobjects.generator.template.TemplateScopeGenerator` wired as an ordinary `` with `