@metaobjectsdev/sdk 0.15.19 → 0.15.21-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/agent-context/README.md
CHANGED
|
@@ -11,4 +11,12 @@ the slim always-on Markdown (`.metaobjects/AGENTS.md` + `CLAUDE.md`) and the six
|
|
|
11
11
|
- `skills/<skill>/SKILL.md` — universal skill body.
|
|
12
12
|
- `skills/<skill>/references/<token>.md` — language fragment; installed iff `<token>` is in the stack.
|
|
13
13
|
|
|
14
|
+
The **scaffolded** set is exactly the six skills in the SDK's `SKILL_NAMES`
|
|
15
|
+
(`src/agent-context/types.ts`) — the assembler emits only those. `skills/`
|
|
16
|
+
additionally holds **`metaobjects-fit-assessment`**, a *pre-adoption* tool that is
|
|
17
|
+
deliberately **not** in `SKILL_NAMES` and so is never scaffolded (a not-yet-adopted
|
|
18
|
+
target has no `.claude/skills/metaobjects-*` to receive it); it carries
|
|
19
|
+
`scaffold: false` in its front-matter as the human marker. Its design + retro-test
|
|
20
|
+
validation live in `docs/superpowers/specs/2026-07-12-metaobjects-fit-assessment-design.md`.
|
|
21
|
+
|
|
14
22
|
Design: `docs/superpowers/specs/2026-06-02-downstream-agent-context-design.md`.
|
|
@@ -65,6 +65,39 @@ code behind a grep hit; a "duplicate" validator's *divergence* is the finding.
|
|
|
65
65
|
subverbs (`--codegen` / `--templates` / `--db`)? Committed-codegen freshness gate?
|
|
66
66
|
Advisories heeded? Routine `--no-verify` bypass? Loader `ERR_*` / warnings addressed?
|
|
67
67
|
Parse the stable `code` field, not message text (ADR-0009).
|
|
68
|
+
**Coverage completeness — "wired" is not "covers it all."** A gate can be present
|
|
69
|
+
yet blind to a whole artifact class. Confirm each subverb actually covers what the
|
|
70
|
+
project HAS: (a) **templates** — `verify --templates` on a CLI before the #193 fix
|
|
71
|
+
SKIPS `template.output @kind=email` and does not body-check a document
|
|
72
|
+
`template.output`'s mustache, so a `{{field}}` that drifted from the payload sails
|
|
73
|
+
through; a project with email/output templates that relies on `verify` alone (no
|
|
74
|
+
`meta gen` + `git diff --exit-code`, and no CLI past the fix) can ship broken —
|
|
75
|
+
**finding**; (b) **codegen** — committed generated code needs `--codegen` (or
|
|
76
|
+
gen+no-diff), else hand-edits/regeneration drift silently; (c) **schema** — `--db`
|
|
77
|
+
(Node `meta` only) for DB drift. Flag a gate that is WIRED BUT INCOMPLETE for the
|
|
78
|
+
artifacts present, and recommend the specific missing coverage.
|
|
79
|
+
- [ ] **F2. Over-generation — unnecessary generated files (codegen WASTE).**
|
|
80
|
+
Generated code is disposable, but that is NOT license to generate what nothing
|
|
81
|
+
consumes. Every generated file is a merge/review/maintenance surface and inflates
|
|
82
|
+
the leverage ratio falsely. Hunt OVER-generation (the inverse of A/B's
|
|
83
|
+
under-generation):
|
|
84
|
+
- **Dead generated files** — an `@generated` file that NOTHING imports or
|
|
85
|
+
references repo-wide (grep the emitted symbol / module path for importers):
|
|
86
|
+
delete it and stop generating it.
|
|
87
|
+
- **Artifacts an entity doesn't need** — REST routes / TanStack grids / forms /
|
|
88
|
+
hooks emitted for an entity that has no such surface. The per-entity opt-outs
|
|
89
|
+
exist for exactly this (`@emitRoutes: false`, `@emitTanstack: false`, a
|
|
90
|
+
`layout.dataGrid`-gated grid): flag the opt-out NOT used where the artifact is
|
|
91
|
+
unused.
|
|
92
|
+
- **Generators wired but unconsumed** — a generator in `metaobjects.config.ts`
|
|
93
|
+
`generators: [...]` (or the per-port equivalent) whose whole output class no
|
|
94
|
+
code imports: drop the generator rather than generate into the void.
|
|
95
|
+
- **Wrong target / duplicate output** — the same logical artifact emitted to two
|
|
96
|
+
places (a mis-set per-target `outDir`), one of which is orphaned.
|
|
97
|
+
Recommend generating ONLY what is consumed — narrow the generator set + use the
|
|
98
|
+
per-entity opt-outs. A smaller, fully-consumed generated surface beats a large one
|
|
99
|
+
with dead files (which also make the leverage ratio lie; discount them from the
|
|
100
|
+
census).
|
|
68
101
|
- [ ] **G. Runtime-contract anti-patterns.** Module-global `db` vs context-as-parameter
|
|
69
102
|
(ADR-0008); wire-canonicalization in the query path vs native in-process return types
|
|
70
103
|
(ADR-0019); runtime reflection to resolve a type from FQN vs generated static imports /
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: metaobjects-fit-assessment
|
|
3
|
+
description: Use BEFORE adopting MetaObjects — assess whether a not-yet-adopted project is a fit, what would migrate, the end-state, and the drift-protection payoff; produces a decision-grade, evidence-cited report. Read-only, propose-only.
|
|
4
|
+
scaffold: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!--
|
|
8
|
+
NOT SCAFFOLDED. This is a PRE-adoption tool, so it is deliberately absent from the
|
|
9
|
+
SDK's `SKILL_NAMES` (`server/typescript/packages/sdk/src/agent-context/types.js`) and
|
|
10
|
+
is never emitted by `meta init` — a target that has not adopted MetaObjects has no
|
|
11
|
+
`.claude/skills/metaobjects-*` to drop it into. This directory is its single source of
|
|
12
|
+
truth. Its sibling is `metaobjects-audit` (POST-adoption; scaffolded). Design +
|
|
13
|
+
retro-test validation: `docs/superpowers/specs/2026-07-12-metaobjects-fit-assessment-design.md`.
|
|
14
|
+
How to run it: point a high-end LLM at a target repo + this file (e.g. paste it, or
|
|
15
|
+
fetch it from GitHub / metaobjects.dev) and let it produce the report below.
|
|
16
|
+
-->
|
|
17
|
+
|
|
18
|
+
# MetaObjects Fit & Migration Assessment
|
|
19
|
+
|
|
20
|
+
_Assessment prompt v1 (post-Phase-0 refinement). Grounded against MetaObjects npm `0.15.x` /
|
|
21
|
+
Maven `7.7.x` — verify every capability claim against the current release before asserting it._
|
|
22
|
+
|
|
23
|
+
You are an AI assistant running a **pre-adoption fit assessment** for MetaObjects
|
|
24
|
+
(https://github.com/metaobjectsdev/metaobjects — the cross-language metadata standard:
|
|
25
|
+
typed entity metadata as the durable spine; generated code as the disposable artifact;
|
|
26
|
+
four pillars: codegen, runtime metadata, drift detection, prompt construction; five ports:
|
|
27
|
+
TypeScript, C#, Java, Kotlin, Python).
|
|
28
|
+
|
|
29
|
+
You are sitting inside a target project that has **not adopted MetaObjects**. Produce a
|
|
30
|
+
decision-grade report answering: is this project a fit, what would migrate, what does the
|
|
31
|
+
after-state look like, what are the benefits — with **drift protection as the centerpiece** —
|
|
32
|
+
and which metadata vocabulary the project isn't asking for but would profit from.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Inputs — elicit if absent
|
|
37
|
+
|
|
38
|
+
1. Repo access (required). For monorepos: which subdirectory/service to scope to.
|
|
39
|
+
2. Stack confirmation (detect, then confirm): language(s), DB, ORM, web framework.
|
|
40
|
+
3. **Trajectory — you MUST ask; it is NOT in the code (see M8).** Is this system expected to
|
|
41
|
+
**grow** (more entities, a second language or service, an LLM surface, a team beyond one
|
|
42
|
+
person), or is it feature-complete and stable at its current size? Is it long-lived, or
|
|
43
|
+
disposable? A repo that will triple and a repo that is finished look **identical in git** —
|
|
44
|
+
and this is the single fact that decides the size-based verdict. If the human doesn't
|
|
45
|
+
answer, do not guess: state the assumption you made and mark the verdict conditional on it.
|
|
46
|
+
4. Whether an LLM/prompt surface exists (scopes pillar 4).
|
|
47
|
+
5. Org constraints that gate verdicts: who owns the schema (DBA-gated?); is generated
|
|
48
|
+
code in the repo acceptable?
|
|
49
|
+
6. Where to write output. Default: `metaobjects-fit/` at the target repo root.
|
|
50
|
+
**Never create `.metaobjects/`** — that directory is the marker of an adopted project.
|
|
51
|
+
|
|
52
|
+
No secrets, no live-DB connection. You read code and migrations only; `verify --db` is
|
|
53
|
+
*described* in the report, never executed.
|
|
54
|
+
|
|
55
|
+
## Deliverables
|
|
56
|
+
|
|
57
|
+
- `metaobjects-fit/fit-assessment.md` — the human report (§ Report contract).
|
|
58
|
+
- `metaobjects-fit/fit-assessment.json` — the machine twin (§ JSON contract). Every
|
|
59
|
+
prediction in the prose must have a JSON twin; a claim that can't be expressed as a
|
|
60
|
+
typed, checkable finding is hand-waving — cut it or fix it.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Non-negotiable method rules
|
|
65
|
+
|
|
66
|
+
**M1 — Read-only, propose-only.** Never edit code, never author metadata files, never
|
|
67
|
+
install anything. Every `metadata_sketch` is a read-only proposal. The bridge to action
|
|
68
|
+
is `meta init` + the adoption skills — point there at the end.
|
|
69
|
+
|
|
70
|
+
**M2 — Evidence discipline.** Every claim about the target cites `file:line` or
|
|
71
|
+
`commit-sha`. Read the code behind every grep hit before citing it — a "duplicate"
|
|
72
|
+
validator's *divergence* is the finding, not the grep hit. An ambiguous archaeology hit
|
|
73
|
+
is dropped, not stretched.
|
|
74
|
+
|
|
75
|
+
**M3 — Ground every capability claim.** Before asserting MetaObjects can generate/gate/
|
|
76
|
+
model something, confirm it against the MetaObjects repo: the registry manifest
|
|
77
|
+
(`fixtures/registry-conformance/expected-registry.json` — the closed vocabulary),
|
|
78
|
+
`docs/features/*.md`, and the actual generator source for the target's port
|
|
79
|
+
(`server/typescript/packages/codegen-ts*`, `server/java/codegen-spring`,
|
|
80
|
+
`server/java/codegen-kotlin` (KotlinPoet generators), `server/csharp/*Codegen*`,
|
|
81
|
+
`server/python/`). A capability you cannot point at in that repo does not go in the
|
|
82
|
+
report. Never cite an unregistered subtype or attribute (ADR-0023: the registry is
|
|
83
|
+
sealed; invented attrs fail load with `ERR_UNKNOWN_ATTR`).
|
|
84
|
+
|
|
85
|
+
**M4 — Not a brochure.** Bias to under-flagging on drift findings (>15% false positives
|
|
86
|
+
kills the assessment). The mandatory "what you will NOT get" section and the per-port
|
|
87
|
+
calibration caps are structural: never promise a capability the target's port lacks.
|
|
88
|
+
|
|
89
|
+
**M5 — Metadata follows the code.** The migration you propose authors metadata to
|
|
90
|
+
REPRODUCE the existing tables, names, types, and nullability exactly. No renames, no
|
|
91
|
+
cleanups, no change-metadata→regen→fix-working-code. Ambiguity goes to the human as a
|
|
92
|
+
marked decision point. Parity-gate every wave before deleting hand-written code.
|
|
93
|
+
|
|
94
|
+
**M6 — Author from the live schema, not the ORM annotations.** Where a live schema (or
|
|
95
|
+
its migration history) and ORM annotations disagree, the schema is the truth — the
|
|
96
|
+
annotations lie (that disagreement is itself a drift finding). State this rule in the
|
|
97
|
+
migration plan.
|
|
98
|
+
|
|
99
|
+
**M7 — Floor and ceiling, both labeled (anti-under-promise guard).** Phase-0 calibration
|
|
100
|
+
showed the failure mode is conservative UNDER-prediction, not over-promising. Your
|
|
101
|
+
verdicts, plan, and benefit numbers stay on the **floor** (the conservative,
|
|
102
|
+
metadata-follows-the-code path). But you must ALSO name the **deep-adoption ceiling**
|
|
103
|
+
for the target's port (§ P5-b) in one clearly-labeled paragraph, tagged
|
|
104
|
+
`horizon: "later"` in JSON and never counted in the benefit numbers. Omitting a real
|
|
105
|
+
option a deep adopter would take is a scored defect, just like inventing one.
|
|
106
|
+
|
|
107
|
+
**M8 — The verdict-deciding fact is not always in the code. Size you can count;
|
|
108
|
+
TRAJECTORY you cannot.** The honest NOT-A-FIT splits in two, and only one half is
|
|
109
|
+
observable:
|
|
110
|
+
- **Structural disqualifiers ARE in the repo** — language outside the five ports, no
|
|
111
|
+
relational store, a non-entity-shaped domain, a DBA-gated schema. Read them, cite them,
|
|
112
|
+
rule on them. These are the only grounds on which you may write a flat `NOT A FIT`.
|
|
113
|
+
- **The economic disqualifier is NOT in the repo.** "Too small for the tooling to pay"
|
|
114
|
+
depends on whether the system will **grow** — and a 3-entity app that will become 90 is
|
|
115
|
+
byte-identical in git to a 3-entity app that is finished forever. **Never infer "this will
|
|
116
|
+
never grow" from a small codebase.** Absence of growth-so-far is not evidence of
|
|
117
|
+
no-growth-to-come (a young repo is small *because it is young*). This is the one place your
|
|
118
|
+
evidence discipline (M2) actively misleads you: there is no `file:line` for intent.
|
|
119
|
+
|
|
120
|
+
So: **ask** (Input 3). If answered, rule on it and say whose answer it was. If unanswered,
|
|
121
|
+
do NOT pick a side — emit **both branches** explicitly, e.g.: *"At 4 entities today the
|
|
122
|
+
spine's leverage does not repay the tooling — if this system is done, don't adopt. If you
|
|
123
|
+
expect it to grow past ~10 entities, add a second language, or add an LLM surface, adopt at
|
|
124
|
+
that point; and note adoption gets more expensive later, because you will be retrofitting a
|
|
125
|
+
spine onto more drift, not less."* Tag such claims `confidence: low` and
|
|
126
|
+
`checkable: false` — they are conditional on a fact you were not given.
|
|
127
|
+
|
|
128
|
+
Corollary for scoring/QA: a "negative control" for this assessment cannot be *any small
|
|
129
|
+
repo* — it must be one whose trajectory is **known** (e.g. retrospectively: it stayed small
|
|
130
|
+
for years). Anything else tests a fact the code does not contain.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## The passes — run all of these BEFORE writing the report
|
|
135
|
+
|
|
136
|
+
### P1 — Stack detection + calibration lock-in
|
|
137
|
+
|
|
138
|
+
Detect language(s), DB, ORM, migration tool, web framework, LLM SDKs. Immediately look
|
|
139
|
+
up the target port's row in the § Calibration table and treat it as a hard cap on every
|
|
140
|
+
promise in the rest of the report.
|
|
141
|
+
|
|
142
|
+
### P2 — Census (the denominator for everything)
|
|
143
|
+
|
|
144
|
+
Count, with locations:
|
|
145
|
+
|
|
146
|
+
**P2-a — Table-first entity census (mandatory reconciliation).**
|
|
147
|
+
The spine models the **database, not the ORM layer**. Real migrations model every live
|
|
148
|
+
table — including junction tables, operational tables (audit logs, queues, tokens), and
|
|
149
|
+
tables the ORM never mapped (touched only by hand SQL/DAOs). An entity-count prediction
|
|
150
|
+
that equals the ORM-class count is a known under-prediction mode. So:
|
|
151
|
+
|
|
152
|
+
1. Reconstruct the **live table set**: walk the migration history (`CREATE TABLE` minus
|
|
153
|
+
`DROP TABLE`) or the checked-in schema; count tables.
|
|
154
|
+
2. Count **ORM/model classes on every lane** — not just the primary one: JPA `@Entity`
|
|
155
|
+
PLUS `@MappedSuperclass`/`@Embeddable`; secondary mapping layers (e.g. a Spring-Data-
|
|
156
|
+
JDBC shadow set); Drizzle tables AND Zod schemas; Pydantic/dataclass models; EF Core
|
|
157
|
+
entity classes. Multiple lanes mapping one table = a drift finding (P3), not double
|
|
158
|
+
counting.
|
|
159
|
+
3. Count **read-model shapes**: list/summary DTOs, hand `SELECT` with joins/GROUP BY
|
|
160
|
+
feeding a DTO, hand-written SQL views → future `object.projection`.
|
|
161
|
+
4. Count **payload/value shapes**: JSON/JSONB column shapes (P2-b), embedded/owned
|
|
162
|
+
types, LLM payload dicts → future `object.value`.
|
|
163
|
+
|
|
164
|
+
Then emit the **reconciliation block** (mandatory in report AND in JSON):
|
|
165
|
+
|
|
166
|
+
| Quantity | Count | Basis |
|
|
167
|
+
|---|---|---|
|
|
168
|
+
| Live tables | N | migration walk |
|
|
169
|
+
| ORM/model classes (all lanes) | N | annotation/class census |
|
|
170
|
+
| → predicted `object.entity` | ≈ live tables (state the delta and why) | every live table incl. junctions + ORM-less tables |
|
|
171
|
+
| → predicted `object.projection` | N | read models, list DTOs, hand views |
|
|
172
|
+
| → predicted `object.value` | N | JSONB shapes, owned types, prompt payloads |
|
|
173
|
+
|
|
174
|
+
Name explicitly that read models and payloads become their **own** objects — the spine's
|
|
175
|
+
object count is normally LARGER than the ORM-class count.
|
|
176
|
+
|
|
177
|
+
**P2-b — Opaque-payload hunt (mandatory pass; do not fold into "misc").**
|
|
178
|
+
Hunt every opaque JSON/JSONB column and schema-in-code-only payload:
|
|
179
|
+
|
|
180
|
+
- DDL/migrations: `jsonb`, `json` column types.
|
|
181
|
+
- Java/Kotlin: `ObjectMapper.readValue`/`writeValue`, `Map<String,Object>` fields,
|
|
182
|
+
`jsonb_set` in SQL strings, `@JdbcTypeCode(SqlTypes.JSON)`.
|
|
183
|
+
- TS: `JSON.parse` + `as`/`any`, `z.unknown()`/`z.record()` on a column, Drizzle
|
|
184
|
+
`jsonb(...)` without a typed `$type`.
|
|
185
|
+
- Python: `dict` fields, `json.loads` on a column, SQLAlchemy `JSON`/`JSONB` untyped.
|
|
186
|
+
- C#: `JsonDocument`/`JObject` columns, string columns holding serialized JSON.
|
|
187
|
+
|
|
188
|
+
Each hit is a candidate **`object.value` + `field.object @objectRef @storage: jsonb`**
|
|
189
|
+
(+`@isArray` for arrays; typed single- and array-of-VO jsonb round-trip codecs are
|
|
190
|
+
conformance-gated in every port). Classify each column: (a) a typed class exists
|
|
191
|
+
somewhere for it (a drifting duplicate — ledger row), or (b) fully opaque — the shape
|
|
192
|
+
exists only as N implicit declarations scattered across reader/writer call sites and
|
|
193
|
+
zero checkable ones (drift signature 6 with implicit copies — often the WORST drift
|
|
194
|
+
exposure in the repo, because nothing can even diff it). Report the counts; carry the
|
|
195
|
+
modeling work as a **named migration-wave item**, not a footnote. (`field.map` is the
|
|
196
|
+
legal interim form for a genuinely open bag; a bag with known keys is a value object.)
|
|
197
|
+
|
|
198
|
+
**P2-c — UI-surface census (renderer-agnostic).**
|
|
199
|
+
A UI surface = any list/table/grid or form with a column set, sort order, filter, or
|
|
200
|
+
page size — **including server-rendered templates** (Thymeleaf/JSP/Razor/ERB/Django),
|
|
201
|
+
admin frameworks, and report/CLI table output. Count them all; do not scope this hunt
|
|
202
|
+
to React. Each grid-shaped surface's column/sort/pagination facts are candidates for
|
|
203
|
+
`layout.dataGrid` (`@columns`, `@defaultSortField`, `@defaultSortOrder`, `@pageSize`).
|
|
204
|
+
|
|
205
|
+
The UI verdict is **two lines, never one**:
|
|
206
|
+
- **UI metadata** — `layout.dataGrid` is cross-port registry vocabulary; authoring it is
|
|
207
|
+
cheap on ANY port and moves the column/sort/page-size facts into the spine even while
|
|
208
|
+
today's renderer is server-side (honest caveat: nothing generates the server-rendered
|
|
209
|
+
template from it — the fact capture and any future web client are the payoff).
|
|
210
|
+
- **UI codegen + runtime** — grid/form/hook generation and the runtime components are
|
|
211
|
+
TS/React/TanStack only. Only THIS line may say "nothing migrates" on a non-TS front end.
|
|
212
|
+
|
|
213
|
+
**P2-d — The rest of the census:** route/handler count (CRUD-shaped vs bespoke);
|
|
214
|
+
validation schemas and where they live; enums vs `CHECK` constraints; migration tooling
|
|
215
|
+
and count; LLM prompt-construction sites (builders, inline strings, parsers — with LOC);
|
|
216
|
+
test posture; out-of-tree consumers of the schema (scripts, sibling services, other
|
|
217
|
+
languages).
|
|
218
|
+
|
|
219
|
+
### P3 — Drift ledger + git archaeology (the centerpiece)
|
|
220
|
+
|
|
221
|
+
For each drift exposure, a ledger row: **sources of truth** (each copy at `file:line`) →
|
|
222
|
+
**divergence today** (field-by-field diff — a live, current divergence is the money
|
|
223
|
+
finding) → **historical evidence** (archaeology) → **the gate that closes it** → the
|
|
224
|
+
signature class. Hunt all ten classes:
|
|
225
|
+
|
|
226
|
+
1. Hand validators shadowing the persistence model.
|
|
227
|
+
2. Field-by-field DTO↔model/row mappers.
|
|
228
|
+
3. camelCase↔snake_case body↔column maps.
|
|
229
|
+
4. Drift-admitting comments (`"keep in sync with"`, `"mirrors the"`, `"matching the"`).
|
|
230
|
+
5. Runtime schema patching (`ALTER TABLE IF NOT EXISTS`, `_ensure_schema()`) — N schema owners.
|
|
231
|
+
6. N declarations of one shape (the headline class) — **including the implicit-copy
|
|
232
|
+
variant from P2-b** (an opaque JSON column whose shape lives only in scattered
|
|
233
|
+
readValue/parse call sites).
|
|
234
|
+
7. *(n/a pre-adoption — `own*()` is a MetaObjects-internal discipline.)*
|
|
235
|
+
8. Hand-written `CREATE VIEW` / read-only SQL mirroring a read model. Run the
|
|
236
|
+
**necessity test**: expressible when every output column is a passthrough
|
|
237
|
+
(`origin.passthrough @from/@via`), a count/sum/avg/min/max (`origin.aggregate
|
|
238
|
+
@agg/@of/@via`, row-scoped with `@filter`), a child collection (`origin.collection`),
|
|
239
|
+
or `extends`-borrowed — and joins follow declared relationships/`identity.reference`
|
|
240
|
+
FKs. Expressible → projection candidate (note: an unmodeled hand view is *unmanaged*
|
|
241
|
+
— invisible to `verify --db`; modeling it is what makes it gateable). Not
|
|
242
|
+
expressible → BESPOKE with a NAMED construct (recursive CTE, window fn, set op,
|
|
243
|
+
`DISTINCT ON`, lateral join). "It's an aggregation" is not a justification.
|
|
244
|
+
9. A closed variant-set hand-modeled per instance (N sibling modules on one payload
|
|
245
|
+
shape) → VOCAB CANDIDATE (advisory only; ADR-0037 ordered test).
|
|
246
|
+
10. One prompt's text/payload/parse scattered across services — a renamed field silently
|
|
247
|
+
degrades the prompt with no build-time signal.
|
|
248
|
+
|
|
249
|
+
**Archaeology (prove it already drifted — "it will drift" lands 10× harder as "it
|
|
250
|
+
already did, twice"):**
|
|
251
|
+
- fix commits that patched ONE copy of a duplicated shape (a later commit patching the
|
|
252
|
+
other copy is the smoking gun);
|
|
253
|
+
- migrations whose titles/headers are drift confessions (`"to match entity"`, `"fix
|
|
254
|
+
... constraint"`, quoted production errors);
|
|
255
|
+
- bug-fix messages with `sync` / `mismatch` / `out of date` / `forgot to update` / `bit-rot`;
|
|
256
|
+
- prompt-string edits with no corresponding payload/parser change (and vice versa);
|
|
257
|
+
- orphaned externalization attempts (config/template files nothing loads).
|
|
258
|
+
|
|
259
|
+
**Cost-of-change exhibit (mandatory when findable):** locate one representative
|
|
260
|
+
field-addition commit and quantify its fan-out (`git show --stat`): N files, M modules,
|
|
261
|
+
which duplicate layers it had to touch. This single exhibit is the drift surface made
|
|
262
|
+
concrete — lead with it.
|
|
263
|
+
|
|
264
|
+
**Gate mapping** — every ledger row names its closing mechanism:
|
|
265
|
+
|
|
266
|
+
| Exposure | Closing gate |
|
|
267
|
+
|---|---|
|
|
268
|
+
| model↔validator↔DTO duplicates (1,2,3,6) | one authored `object.entity`; copies become `@generated`; **`meta verify --codegen`** (TS) / **`mvn metaobjects:verify -Dmeta.verify.mode=codegen`** (JVM) / **`dotnet meta verify`** (C#) / **`metaobjects verify`** (Python) in CI |
|
|
269
|
+
| schema vs model (5 + the DDL copy in 6) | spine owns DDL via `meta migrate`; **`meta verify --db`** (Node `meta` only; PG/SQLite/D1) |
|
|
270
|
+
| opaque JSON columns (6-implicit) | `object.value` + `field.object @storage: jsonb` — the shape gets ONE checkable declaration + generated codecs |
|
|
271
|
+
| read-model SQL (8) | `object.projection` + `origin.*` generate the view DDL |
|
|
272
|
+
| scattered prompts (10) | `template.prompt` + typed payload VO + external text; **`meta verify --templates`** / `Renderer.verify` fails when a `{{field}}` no longer matches the payload; `template.output` (FR-006) + the tolerant `extract` parser and output-format fragment (FR-010) generate both sides of the tag contract |
|
|
273
|
+
| the metadata itself | strict provenance (ADR-0023): unknown attrs fail load |
|
|
274
|
+
|
|
275
|
+
State the honest limits in the same section: `verify` cannot catch semantic mismodeling
|
|
276
|
+
(a uuid modeled as string passes `--db`), cannot see unmodeled DB objects, and
|
|
277
|
+
`--templates` coverage depends on CLI version. A gate, not a proof system.
|
|
278
|
+
|
|
279
|
+
### P4 — Fit rubric (worked, not vibes)
|
|
280
|
+
|
|
281
|
+
Positive signals (cite each): backend in one of the five ports; relational persistence
|
|
282
|
+
(especially PG/SQLite); ≥ ~5 entity-shaped things with CRUD-ish surfaces; the same shape
|
|
283
|
+
declared ≥2× today (the strongest predictor — it IS drift exposure); LLM prompt sites
|
|
284
|
+
(any count); >1 language consuming one model; existing/planned admin grids or forms.
|
|
285
|
+
|
|
286
|
+
Disqualifier table — **every row answered, not just failing ones** (a verdict without
|
|
287
|
+
this table worked row-by-row is invalid output):
|
|
288
|
+
|
|
289
|
+
| Check | Consequence |
|
|
290
|
+
|---|---|
|
|
291
|
+
| Backend language outside TS/Java/Kotlin/C#/Python | NOT A FIT (codegen/runtime); prompt pillar only if a portable sidecar makes sense — usually no |
|
|
292
|
+
| No relational store | persistence + `--db` N/A; assess prompt + value/projection pillars on their own merits |
|
|
293
|
+
| DB not Postgres/SQLite/D1 | schema pillar (`migrate`, `verify --db`) OUT — say so plainly; data-access unaffected |
|
|
294
|
+
| Non-entity-shaped domain (no persistent typed records to speak of) | NOT A FIT — structural, and visible in the code |
|
|
295
|
+
| Few entities today (< ~5) | **NOT a flat verdict — this is the M8 trap.** Small-today ≠ small-forever, and git cannot tell you which. Use the trajectory answer (Input 3): *done at this size* → MARGINAL/NOT A FIT (say so plainly — the leverage won't repay the tooling); *expected to grow / add a language / add an LLM surface* → FIT, and note adopting later costs more (you'd retrofit a spine onto more drift). **Unanswered → emit both branches, never guess.** |
|
|
296
|
+
| Schema owned by another team (DBA-gated) | migrate pillar restricted; model read-only ("metadata follows the schema"); flag the org constraint |
|
|
297
|
+
| Deep hand-tuned ORM investment | churn warning, not a disqualifier: the plan must reproduce those mappings (`@column`/`@table`/`@dbColumnType`) and price it |
|
|
298
|
+
| Team rejects generated code in the repo | flag; regen-every-build works but `verify --codegen` semantics differ — call the tradeoff |
|
|
299
|
+
|
|
300
|
+
### P5 — Migration plan
|
|
301
|
+
|
|
302
|
+
**P5-a — Waves (the floor).** Wave 0: wedge — a handful of highest-churn tables authored
|
|
303
|
+
from the live schema (M6) + the drift gate (`verify --db` where the DB qualifies) wired
|
|
304
|
+
in CI, expected day-one catches named from the ledger; zero generated code, zero app
|
|
305
|
+
churn. Wave 1: retire the clearest deletable duplicate layer + generate the DTO/API
|
|
306
|
+
surface the port offers; codegen-drift gate in CI. Wave 2: full entity spine + schema
|
|
307
|
+
ownership handover (or read-only modeling), relationships (`identity.reference`,
|
|
308
|
+
FR-018 `@through` junctions), **the P2-b value-object modeling as a named item**.
|
|
309
|
+
Wave 3: UI metadata (P2-c) where surfaces exist; UI codegen only on TS/web. Wave 4:
|
|
310
|
+
prompts, wedge-first per site, parity-gated byte-compare against existing outputs.
|
|
311
|
+
Each wave: scope, LOC retired, effort band, parity gate, the adoption skill that
|
|
312
|
+
executes it (`metaobjects-authoring` / `-codegen` / `-runtime-ui` / `-prompts` /
|
|
313
|
+
`-verify`).
|
|
314
|
+
|
|
315
|
+
**P5-b — The deep-adoption ceiling (one labeled paragraph; `horizon: "later"`).** Name
|
|
316
|
+
what the port's maximal lane looks like for adopters who go all the way, without
|
|
317
|
+
promising it or counting it in benefits:
|
|
318
|
+
- **JVM**: the stock Java/Spring lane keeps hand-written entities (generates DTO records,
|
|
319
|
+
controllers, filter allowlists, repository interfaces) — but the Kotlin lane
|
|
320
|
+
(`codegen-kotlin`) generates the entity + Exposed table + validators themselves
|
|
321
|
+
(generated-base + hand-written-subclass ownership), and OMDB offers metadata-driven
|
|
322
|
+
data access; a deep JVM adopter can end with the ORM layer itself generated/replaced.
|
|
323
|
+
- **TS**: full stack (Drizzle schema + Zod + routes + hooks + grids) — the floor is
|
|
324
|
+
already near the ceiling.
|
|
325
|
+
- **C#**: generated EF Core entities + `AppDbContext` + minimal-API routes; EF Core stays
|
|
326
|
+
the runtime.
|
|
327
|
+
- **Python**: generated Pydantic + `APIRouter` + `ObjectManager` runtime data access.
|
|
328
|
+
- All ports: **scaffold-and-own (ADR-0034)** means adopters own and extend generators —
|
|
329
|
+
the stock generator set is the starting point, not the cap on what can become
|
|
330
|
+
`@generated`. When a large hand-written layer is metadata-derivable but no stock
|
|
331
|
+
generator emits it, say so: "an owned generator can retire this" (honest effort tag).
|
|
332
|
+
|
|
333
|
+
### P6 — End-state projection
|
|
334
|
+
|
|
335
|
+
- **Spine size — derive from DDL richness, not a flat guess.** Real spines carry the
|
|
336
|
+
full physical structure: identities, `identity.reference` per FK, `identity.secondary`
|
|
337
|
+
per unique constraint, `index.lookup` per performance index, enums, validators. Count
|
|
338
|
+
per-table indexes + uniques + FKs + enum-CHECKs in the DDL and pick the lines-per-
|
|
339
|
+
entity band accordingly: ~25–40 only for bare tables; index/FK-rich schemas run
|
|
340
|
+
~80–120 lines/entity. Multiply by the **reconciled** object count from P2-a (entities
|
|
341
|
+
+ projections + values), not the ORM-class count. Give a range.
|
|
342
|
+
- **Generated surface**: files + LOC per the port's actual generators (read them — M3).
|
|
343
|
+
- **Leverage ratio** = `generated_lines / (metadata_lines + owned_generator_lines)`;
|
|
344
|
+
give a band, note it excludes the drift-gate value (the real prize, not
|
|
345
|
+
line-denominated).
|
|
346
|
+
- **Stays-hand-written table**: every surface predicted to remain bespoke, each with a
|
|
347
|
+
NAMED justification (recursive CTE, window fn, auth, business logic, transports).
|
|
348
|
+
|
|
349
|
+
### P7 — Beyond-the-ask vocabulary hunt (apply the ADR-0037 ordered test to each)
|
|
350
|
+
|
|
351
|
+
- money as float / hand `*100` → `field.currency` (+`view.currency @locale`) — but NOT
|
|
352
|
+
for non-ISO-4217 quantities (game gold, points): those are `field.int`/`field.long`.
|
|
353
|
+
- string-union / `CHECK IN (...)` / int-flag discriminators → `field.enum @values`
|
|
354
|
+
(plain value-set enums only; enums carrying behavior stay code, or split value-set
|
|
355
|
+
from behavior).
|
|
356
|
+
- UUIDs as bare strings → `field.uuid` (never `field.string` + `@dbColumnType: uuid`).
|
|
357
|
+
- hand `COUNT/SUM` subqueries, read-model SQL → `object.projection` + `origin.passthrough`
|
|
358
|
+
/ `origin.aggregate` (+`@filter` for scoped aggregates) / `origin.collection`.
|
|
359
|
+
**Calibration: most projection fields in real spines are passthrough/`extends`
|
|
360
|
+
re-exposures; aggregates are the minority — lead with passthrough.**
|
|
361
|
+
- hand junction joins → `relationship @cardinality: many @through` (junction declares
|
|
362
|
+
two `identity.reference` children; FR-018).
|
|
363
|
+
- copy-pasted base-field blocks → abstract base + `extends`.
|
|
364
|
+
- unique business keys / lookup indexes living only in DDL → `identity.secondary` /
|
|
365
|
+
`index.lookup` (these are usually the single largest invisible-structure class —
|
|
366
|
+
count them).
|
|
367
|
+
- email/URL/IP regexes → `@stringFormat: email` / `field.uri` / `field.inet`.
|
|
368
|
+
- opaque JSON columns → `object.value` + `field.object @storage: jsonb` (from P2-b).
|
|
369
|
+
- inline prompts / ad-hoc payload dicts / regex output parsing → `template.prompt` /
|
|
370
|
+
`template.output` / `template.toolcall`.
|
|
371
|
+
- doc comments hand-written in migrations (`COMMENT ON`) → the common `description` attr.
|
|
372
|
+
- a recurring closed variant-set as N sibling modules → project-registered provider
|
|
373
|
+
subtype — VOCAB CANDIDATE, advisory only, never load-bearing for the verdict.
|
|
374
|
+
|
|
375
|
+
Each suggestion: `metadata_sketch` + honest effort. Bias to under-flagging, but note:
|
|
376
|
+
under-suggestion is also scored — if a hunt line above has hits, it must appear.
|
|
377
|
+
|
|
378
|
+
### P8 — Limits (feeds §R7)
|
|
379
|
+
|
|
380
|
+
Work the § Calibration table for the target's port. Non-negotiable inclusions: schema
|
|
381
|
+
migration is Node-`meta`-only (PG/SQLite/D1); filter-operator route codegen full only in
|
|
382
|
+
TS; C# has no ObjectManager tier; Python hand-wires the FastAPI router; business logic /
|
|
383
|
+
irreducible SQL / auth / bespoke viz stay hand-written; generated code runs without
|
|
384
|
+
MetaObjects at runtime (local-first) but adopting means owning a codegen step; metadata
|
|
385
|
+
authoring debt is real — price the wave-0 reconciliation; early `verify --db` runs will
|
|
386
|
+
surface legacy oddities — triage as findings, not noise.
|
|
387
|
+
|
|
388
|
+
**State this limit explicitly in §R7 (M8):** *this assessment can read your code, not your
|
|
389
|
+
roadmap.* It counts what exists; it cannot see whether the system will grow, and growth is
|
|
390
|
+
what decides the size-based verdict. Where the trajectory answer was given, name who gave it;
|
|
391
|
+
where it wasn't, say which branch you assumed. An assessment that quietly converts "small
|
|
392
|
+
today" into "not worth it, ever" is exactly the false negative this section exists to prevent.
|
|
393
|
+
|
|
394
|
+
---
|
|
395
|
+
|
|
396
|
+
## Report contract — `fit-assessment.md`, sections in this order
|
|
397
|
+
|
|
398
|
+
**§R0 — Verdict block.** Per-pillar verdicts (codegen / runtime metadata / drift
|
|
399
|
+
detection / prompt construction): `STRONG FIT` / `FIT` / `MARGINAL` / `NOT A FIT` /
|
|
400
|
+
`N/A`, one decisive fact each (pillar-scoped because real projects are lopsided).
|
|
401
|
+
Overall verdict + confidence + the three decisive facts. The disqualifier table, worked.
|
|
402
|
+
The one-line wedge recommendation. **The UI pillar line follows the P2-c two-line split.**
|
|
403
|
+
|
|
404
|
+
**§R1 — Drift exposure today** (the centerpiece; immediately after the verdict): the
|
|
405
|
+
cost-of-change exhibit, then the ledger (sources → divergence-today → archaeology →
|
|
406
|
+
gate → class), then the gate-mapping table + honest limits, then a ledger summary line
|
|
407
|
+
(N classes; N with documented past incidents; N divergent right now).
|
|
408
|
+
|
|
409
|
+
**§R2 — Census** — including the **P2-a reconciliation block**, the **P2-b opaque-payload
|
|
410
|
+
counts**, and the renderer-agnostic UI-surface counts, with a coverage column (what
|
|
411
|
+
MetaObjects can model/generate against vs what it will never touch).
|
|
412
|
+
|
|
413
|
+
**§R3 — Migration plan** — waves per P5-a, governed by metadata-follows-the-code +
|
|
414
|
+
author-from-live-schema, **plus the single labeled deep-adoption-ceiling paragraph
|
|
415
|
+
(P5-b)**.
|
|
416
|
+
|
|
417
|
+
**§R4 — End-state projection** — spine estimate (DDL-richness-derived band × reconciled
|
|
418
|
+
object count), generated surface, leverage ratio band, stays-hand-written table.
|
|
419
|
+
|
|
420
|
+
**§R5 — Benefits, quantified and tagged** — LOC eliminated by class; drift classes
|
|
421
|
+
closed (cross-referenced to §R1 rows); incident prevention where archaeology shows past
|
|
422
|
+
production errors; cross-language reuse only if genuinely multi-language; prompt wins
|
|
423
|
+
(byte-stable renders, payload-as-diff, build-time template verify). Each tagged
|
|
424
|
+
`checkable: true/false`; uncheckable benefits allowed but labeled.
|
|
425
|
+
|
|
426
|
+
**§R6 — Beyond-the-ask vocabulary opportunities** (P7 output, each with sketch + effort).
|
|
427
|
+
|
|
428
|
+
**§R7 — What you will NOT get** (P8 output; mandatory).
|
|
429
|
+
|
|
430
|
+
**§R8 — First-week wedge plan.** One real entity-set end-to-end: author metadata
|
|
431
|
+
reproducing the existing shape from the live schema → wire the drift gate into CI in
|
|
432
|
+
week one (the earliest, cheapest payoff) → name the expected day-one catches from the
|
|
433
|
+
ledger → one generated vertical + one deleted duplicate as the codegen proof. Then point
|
|
434
|
+
at `meta init` + the adoption skills.
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## JSON contract — `fit-assessment.json`
|
|
439
|
+
|
|
440
|
+
```jsonc
|
|
441
|
+
{
|
|
442
|
+
"assessed_project": "<path or name>",
|
|
443
|
+
"assessment_version": "v1",
|
|
444
|
+
"date": "YYYY-MM-DD",
|
|
445
|
+
"verdicts": {
|
|
446
|
+
"overall": "ADOPT | ADOPT-STAGED | MARGINAL | NOT-A-FIT",
|
|
447
|
+
"confidence": "high | medium | low",
|
|
448
|
+
"pillars": { "codegen": "...", "runtime": "...", "drift": "...", "prompts": "..." }
|
|
449
|
+
},
|
|
450
|
+
"census_reconciliation": { // mandatory — makes entity-count claims scoreable
|
|
451
|
+
"live_tables": 0,
|
|
452
|
+
"orm_model_classes_all_lanes": 0,
|
|
453
|
+
"predicted_object_entity": 0,
|
|
454
|
+
"predicted_object_projection": 0,
|
|
455
|
+
"predicted_object_value": 0,
|
|
456
|
+
"opaque_json_columns": 0,
|
|
457
|
+
"ui_surfaces_total": 0, // renderer-agnostic count (P2-c)
|
|
458
|
+
"prompt_sites": 0
|
|
459
|
+
},
|
|
460
|
+
"claims": [
|
|
461
|
+
{
|
|
462
|
+
"id": "kebab-stable-id",
|
|
463
|
+
"claim_type": "fit | census | drift | migrates | stays-bespoke | leverage | benefit | vocab | limit | wedge",
|
|
464
|
+
"claim": "one-sentence prediction",
|
|
465
|
+
"pillar": "codegen | runtime | drift | prompt | n/a",
|
|
466
|
+
"surface": "entity | dto | validator | repository | route | view | ui | prompt | migration | schema | payload",
|
|
467
|
+
"capability": "the registry capability this maps to (e.g. field.enum, origin.passthrough, template.output)",
|
|
468
|
+
"locations": ["file:line", "commit-sha"],
|
|
469
|
+
"evidence": "what was read/verified",
|
|
470
|
+
"impact": "LOC / call-sites / risk",
|
|
471
|
+
"effort": "trivial | small | medium | large",
|
|
472
|
+
"confidence": "high | medium | low",
|
|
473
|
+
"checkable": true,
|
|
474
|
+
"horizon": "now | later", // "later" = deep-adoption ceiling; never counted in benefits
|
|
475
|
+
"metadata_sketch": "optional — read-only proposal",
|
|
476
|
+
"parity_gate": "optional — the check proving behavior-equivalence"
|
|
477
|
+
}
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Every prose prediction gets a claim. Ceiling statements (P5-b) MUST carry
|
|
483
|
+
`horizon: "later"`. Drift-ledger rows MUST carry `checkable: true` with real locations.
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## Calibration — per-port caps (never promise across these lines)
|
|
488
|
+
|
|
489
|
+
- **Schema pillar** (`meta migrate`, `verify --db`): Node `meta` CLI only; Postgres,
|
|
490
|
+
SQLite, D1 only. Any other DB or a no-Node shop: the schema pillar is out — data
|
|
491
|
+
access still works; say it plainly.
|
|
492
|
+
- **TS**: full stack — Drizzle/Zod/Fastify codegen, filter-operator routes, TanStack/React
|
|
493
|
+
UI runtime, migrations. The only port with UI codegen + runtime.
|
|
494
|
+
- **Java/Spring**: generated DTO records, controllers, filter allowlists (pagination/sort;
|
|
495
|
+
filter ops deferred), repository *interfaces* (consumer implements — existing ORM sits
|
|
496
|
+
behind unchanged), payload records, output parsers hand-write the Jackson one-liner;
|
|
497
|
+
entities stay hand-written on this lane; Maven `meta:gen` / `meta:verify`
|
|
498
|
+
(`codegen`/`templates` modes — no live-DB mode).
|
|
499
|
+
- **Kotlin/JVM**: `codegen-kotlin` generates entity + Exposed table + Spring controller +
|
|
500
|
+
payload + relations + filter allowlist + validators + output parsers (runs via Maven
|
|
501
|
+
`meta:gen`).
|
|
502
|
+
- **C#**: generated EF Core entities + `AppDbContext` + CRUD minimal-API routes +
|
|
503
|
+
render/payload/verify via `dotnet meta gen`/`verify`; no ObjectManager runtime tier;
|
|
504
|
+
no migrate surface (TS-owned).
|
|
505
|
+
- **Python**: generated Pydantic + `APIRouter` + payload/parsers + `ObjectManager`
|
|
506
|
+
runtime; consumer hand-wires the FastAPI router + repository impl; `metaobjects`
|
|
507
|
+
console script `gen`/`verify` (no migrate).
|
|
508
|
+
- **Prompt pillar** (all five ports): render + payload-VO codegen + `verify` templates +
|
|
509
|
+
`template.output` parser-on-receipt (FR-006) + output-format fragment & tolerant
|
|
510
|
+
`extract` (FR-010). MCP exposure of declared prompts/tools: not shipped — never
|
|
511
|
+
promise it.
|
|
512
|
+
- **Not shipped, never promise**: `api.*`/`operation.*`/`binding.*` declared-API surface;
|
|
513
|
+
the cut `byte`/`short`/`class` field stubs (non-functional, removed from the registry);
|
|
514
|
+
`index.fulltext`/`vector`/`spatial` (reserved, unregistered); native PG enums /
|
|
515
|
+
int-backed enums (deferred).
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
## Final self-check before writing
|
|
520
|
+
|
|
521
|
+
0. **Trajectory (M8): did you ASK, or did you infer "won't grow" from a small repo?** A flat
|
|
522
|
+
NOT-A-FIT is legal ONLY on a structural disqualifier. If the size row is doing the work and
|
|
523
|
+
the trajectory answer is missing, you must show both branches — not a verdict.
|
|
524
|
+
1. Disqualifier table worked row-by-row? (Invalid output otherwise.)
|
|
525
|
+
2. Census reconciliation block present, with predicted `object.entity` anchored to live
|
|
526
|
+
tables, not ORM classes?
|
|
527
|
+
3. Opaque-payload hunt run and reported, with the value-object modeling in a named wave?
|
|
528
|
+
4. UI verdict split into metadata-authoring vs codegen/runtime lines, with
|
|
529
|
+
server-rendered surfaces counted?
|
|
530
|
+
5. Spine estimate derived from DDL richness × reconciled object count?
|
|
531
|
+
6. Deep-adoption ceiling paragraph present, labeled, `horizon: "later"`?
|
|
532
|
+
7. Every drift row: real `file:line`, real commits, a named gate? (>15% false positives
|
|
533
|
+
is fatal.)
|
|
534
|
+
8. Every capability claim traceable to the registry/docs/generator source?
|
|
535
|
+
9. "What you will NOT get" complete for this port?
|
|
536
|
+
10. Every prose prediction has a JSON twin?
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metaobjectsdev/sdk",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.21-rc.1",
|
|
4
4
|
"description": "Workspace helpers and agent-docs utilities for MetaObjects projects.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@metaobjectsdev/metadata": "0.15.
|
|
59
|
+
"@metaobjectsdev/metadata": "0.15.21-rc.1",
|
|
60
60
|
"zod": "^3.23.0"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|