Metadata Loader — Kernel Protocol reference
How the runtime MetadataManager is wired: which datasource backs sys_metadata, what to fall back to when that datasource is unreachable.
Metadata Manager Configuration
How the runtime MetadataManager is wired: which datasource backs sys_metadata, what to fall back to when that datasource is unreachable, cache / watch / validation settings, and the persistence write gates.
The loader and watch envelope types (MetadataFormat, MetadataStats, MetadataLoadOptions, MetadataWatchEvent, MetadataLoaderContract, …) are NOT here — they live in @objectstack/spec/system (system/metadata-persistence.zod), which is their single source.
Source: packages/spec/src/kernel/metadata-loader.zod.ts
TypeScript Usage
import { MetadataFallbackStrategySchema, MetadataManagerConfigSchema } from '@objectstack/spec/kernel';
import type { MetadataFallbackStrategy, MetadataManagerConfig } from '@objectstack/spec/kernel';
// Validate data
const result = MetadataFallbackStrategySchema.parse(data);MetadataFallbackStrategy
Allowed Values
filesystemmemorynone
MetadataManagerConfig
Properties
| Property | Type | Required | Description |
|---|---|---|---|
| datasource | string | optional | Datasource name reference for database persistence |
| tableName | string | optional (default: "sys_metadata") | Database table name for metadata storage |
| fallback | Enum<'filesystem' | 'memory' | 'none'> | optional (default: "none") | Fallback strategy when datasource is unavailable |
| rootDir | string | optional | Root directory path |
| formats | Enum<'yaml' | 'json' | 'typescript' | 'javascript'>[] | optional (default: ["typescript","json","yaml"]) | Enabled formats |
| cache | { databaseLoader?: object } | optional | Cache settings — only databaseLoader is read at runtime; the outer keys are retired |
| watch | boolean | optional (default: false) | Enable file watching |
| watchOptions | { ignored?: string[]; persistent?: boolean; ignoreInitial?: boolean } | optional | File watcher options |
| validation | { strict?: boolean; throwOnError?: boolean } | optional | Validation settings |
| loaderOptions | Record<string, any> | optional | Loader-specific configuration |
| persistence | { writable?: boolean } | optional | Persistence write gates |
Nested Shape: MetadataManagerConfig.cache
| Property | Type | Required | Description |
|---|---|---|---|
| enabled | never | optional | [REMOVED] cache.enabled was removed from MetadataManagerConfig in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it: the outer cache block was declared and documented but consumed by no runtime, so enabled: false switched nothing off. Delete the key. The cache that actually runs is the DatabaseLoader read-through LRU under cache.databaseLoader; its enabled is the switch that is honoured. |
| ttlSeconds | never | optional | [REMOVED] cache.ttlSeconds was removed from MetadataManagerConfig in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it: the outer cache block was declared and documented but consumed by no runtime, so the number expired nothing. Delete the key. The TTL that is honoured is cache.databaseLoader.ttlMs (milliseconds, default 60000) on the DatabaseLoader read-through cache. |
| ttl | never | optional | [REMOVED] cache.ttl was removed from MetadataManagerConfig in @objectstack/spec 17 — nothing ever read it: the outer cache block was declared and documented but consumed by no runtime, and its unit-suffixed respelling ttlSeconds was retired with it before it shipped (ADR-0049 enforce-or-remove). Delete the key. The TTL that is honoured is cache.databaseLoader.ttlMs (milliseconds, default 60000) on the DatabaseLoader read-through cache. |
| maxSize | never | optional | [REMOVED] cache.maxSize was removed from MetadataManagerConfig in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — nothing ever read it: the outer cache block was declared and documented but consumed by no runtime, so the byte cap capped nothing. Delete the key. The cap that is honoured is cache.databaseLoader.maxSize (an entry count, default 500) on the DatabaseLoader read-through cache. |
| databaseLoader | { enabled?: boolean; maxSize?: integer; ttlMs?: integer } | optional | DatabaseLoader read-through cache |
Nested Shape: MetadataManagerConfig.watchOptions
| Property | Type | Required | Description |
|---|---|---|---|
| ignored | string[] | optional | Patterns to ignore |
| persistent | boolean | optional (default: true) | Keep process running |
| ignoreInitial | boolean | optional (default: true) | Ignore initial add events |
Nested Shape: MetadataManagerConfig.validation
| Property | Type | Required | Description |
|---|---|---|---|
| strict | boolean | optional (default: true) | Strict validation |
| throwOnError | boolean | optional (default: true) | Throw on validation error |
Nested Shape: MetadataManagerConfig.persistence
| Property | Type | Required | Description |
|---|---|---|---|
| writable | boolean | optional (default: true) | Allow base metadata writes via register() |
| overlayWritable | never | optional | [REMOVED] persistence.overlayWritable was removed from MetadataManagerConfig in @objectstack/spec 17 (ADR-0049 enforce-or-remove) — the only thing it gated was MetadataManager.saveOverlay(), a paper-protocol method no route or UI ever called, removed with the metadata-customization protocol (ADR-0126 supersedes it on the record). Delete the key. The base write gate that remains is persistence.writable; the real org-overlay writes (ADR-0005) ride the REST meta write doors' manage_metadata permission gate, not this flag. |
Execution Context
Execution Context schemas of the ObjectStack Kernel Protocol: AuthGateCode and 2 more — each property with its type, default and a TypeScript example.
Metadata Plugin
Defines the specification for the Metadata Plugin — the central authority responsible for managing ALL metadata across the ObjectStack platform.