title: Migrating to 9.0 — your fields and system fields
slug: guides/namespace-migration
public: true
category: guides
template: guide
order: 1
description: The simple story of the 9.0 field-addressing change and the mechanical checklist for updating your call sites — every miss fails loudly with the fix in the error.
next:
- concepts/field-addressing
---
# Migrating to 9.0 — your fields and system fields
The one-sentence version: **your data's field names are now completely
yours, the engine's own fields all live behind one `system.` prefix, and
nothing in between can silently go wrong anymore.**
## What changed, simply
**1. Any field name just works.** Before 9.0 the engine quietly owned
certain names. A field called `level` could be shadowed by the engine's
internal index layer of the same name (sorts silently returned insertion
order); names like `confidence` or `subtype` were rejected inside
`metadata`; names like `content` or `id` were silently never indexed, so
filtering on them returned nothing. All of that is gone. Any name —
`level`, `confidence`, `type`, `id`, `content`, anything — is stored
exactly as written and works with every feature: filtering, sorting,
grouping, aggregation, search, and time-travel reads.
**2. The engine's fields moved behind `system.`.** The engine still keeps
its own per-record bookkeeping — creation time, type, confidence, and so
on. Those are reached one way only now: spelled out, e.g.
`system.createdAt`, `system.type`. They are just as queryable and sortable
as before. `orderBy: 'createdAt'` means *your* field named `createdAt`;
`orderBy: 'system.createdAt'` means the engine's timestamp. No guessing,
no priority rules.
**3. Storage keeps the two physically separate.** New records store your
metadata in its own nested compartment, so a user field named
`confidence` and the engine's confidence live side by side, both intact,
through restarts, index rebuilds, and `asOf()` history. Old records stay
readable forever; nothing rewrites your data.
**4. Mistakes are loud.** An ambiguous or unknown field name is a typed
error naming the fix. Unimplemented options refuse instead of being
ignored. The only forbidden name in your metadata is one literally
starting with `system.`.
## The mechanical checklist
Every missed site fails **loudly** with the correction in the error
message — nothing silently changes meaning. Sweep these patterns:
| `metadata: { confidence: 0.9 }` expecting a throw or a lift to the engine scalar | it is YOUR field now — set the engine scalar via the `confidence` param |
| `new Brainy({ reservedFieldPolicy: … })` | remove the option (it throws with this note) |
| `find({ cursor })` / `includeRelations` / `writeOnly` | refuse with `UnsupportedFindOptionError` — they were silently ignored before |
If a bare name in a query was genuinely *your* field all along (`orderBy: