1. Adopt the predecessor storage
You see: startup refuses with--state-dir is exactly the directory the refusal names: the
persistent_state of rpc_gateway and the SDK builders, or the store
directory of meta_gateway. --apply writes a meta-adoption.json journal
and resumes from it: if a run is interrupted, startup refuses with
the predecessor adoption at <path> is unfinished, and running the same
command again finishes it. The gateway homes are separate inputs: a refusal
that names the predecessor (pre-0.9) gateway home carries the exact
--predecessor-home and --gateway-home arguments to add.
Since 0.9.2, pass the mob definition the installation boots with as well,
--mob-config <mob.toml> (or its definition.json; once per mob), so the dry
run also checks it for keys that the MobKit release which created a store
ignored and Meta 0.9 applies. See
Keys that now take effect.
In 0.9.1 a bare --state-dir <dir> touches only that directory: the
predecessor database renames, the ledger domains and the metadata table, the
composition manifests, the memory ledger file, the steward schedule, and the
realm id recorded in the journal. It touches no gateway home and no runtime
registry outside the directory. Add --user-gateway-home to also carry over
the user-level gateway home ($XDG_STATE_HOME/meerkat-meta, else
~/.local/state/meerkat-meta, from its predecessor sibling
meerkat-mobkit), which 0.9.0 did by default. --gateway-home, with or
without --predecessor-home, works as before, but --predecessor-home
without --gateway-home is now a usage error (exit 2). An unfinished
adoption resumes with the homes its journal recorded.
The composition manifest written by MobKit
A persistent mob storage keeps a provenance file beside its event log,<storage file>.composition.json (for example
event_log.sqlite3.composition.json). MobKit wrote its creator field as
created_by_mobkit; Meta 0.9 names it created_by_meta.
You see (0.9.0): an adopted store is refused at init with JSON-RPC
-32019, data kind: "malformed", when the mob storage is persistent (the
default without runtime_options.mob_storage), its event log already holds
events, and the launch is authoritative:
created_by_mobkit as created_by_meta
(a manifest that carries both keys is refused as malformed), and
storage-adopt-predecessor renames the key inside its journaled ledger
step, so a stock 0.8.x store lists one more action than on 0.9.0:
complete=false;
--apply renames the key and completes the adoption. To check or rewrite
manifests on their own, run
meta_repair --composition-manifests <state dir | manifest file> [--apply]
(a dry run by default; it exits 1 if any manifest is refused).
Do (0.9.0): in each *.composition.json, rename that one key,
created_by_mobkit to created_by_meta, and change nothing else in the file.
The rename is the whole fix.
The extension document store and document MCP descriptors
Hosts built with theextension-state feature keep their documents in
<state>/extension_state.sqlite3. The file name and the schema did not
change in 0.9; the store’s schema ledger domain did, from
mobkit-extension-state to meta-extension-state.
You see (0.9.0, 0.9.1): the store fails to open with an unledgered
objects error for the domain meta-extension-state (the tables
extension_documents and extension_receipts), also after a completed
adoption, because the adoption did not carry that domain over.
Do (0.9.2): the store is predecessor state now. Startup refuses with the
adoption message above; run meta_gateway storage-adopt-predecessor as
described there. An installation an earlier 0.9 adoption already finished
lists one more action, the store’s ledger domain, and --apply renames it.
Every document is kept. The stock meta_gateway adopts the store too: it
does not need the extension-state feature.
A document MCP descriptor that a mob definition persisted before 0.9 (a
child profile created by an agent mob_create, for example) carries the
public marker under its predecessor name MOBKIT_MCP_DOCUMENT_BINDING. 0.9.2
resolves it to your host’s document binding exactly as the current
META_MCP_DOCUMENT_BINDING spelling, so such members keep their documents.
Nothing needs to change in the stored definitions. A marked descriptor that
no binding resolves refuses the member’s build, in either spelling, with or
without the extension-state feature.
2. Profile prompt keys are refused
You see:prompt and instructions. On meta_gateway 0.9.0
the init refusal read only failed to parse <workspace>/config/mob.toml;
0.9.1 includes the reason.
Why: a profile has no prompt field. MobKit 0.8.31 and earlier dropped
these keys without a warning, so the key had no effect on the members of that
profile: their prompt came from the profile’s skills, another supported
source or the default, never from this key.
Do: delete the key. That keeps exactly the behaviour the deployment had,
and it never makes a persistent store divergent. To set the members’ prompt,
list a skill in the profile:
additional_instructions
(DurableAgentSpec) or an agent customizer’s draft.system_prompt.
Adding a skill, unlike deleting the refused key, changes the composition: on a
persistent store it refuses as divergent (naming profiles.<name>.skills
and skills.<id>) until you advance the stored definition once with the
one-shot mob definition update.
3. Other mob.toml shapes that now refuse
MobKit 0.8.x dropped each of these without a warning.model_fallback on a realm profile reference. A profile that sets
realm_profile = "..." and model_fallback refuses with:
[runtime] model_fallback.
A [runtime] table with other keys. [runtime] is now part of the mob
definition and accepts only model_fallback. Any other key refuses with:
config.toml.
[self_hosted] or [realm] tables in mob.toml. Refused with:
config.toml and point the gateway at it; see
Self-hosted models and the Meerkat host config.
4. Keys that now take effect
Earlier MobKit releases ignored these keys inmob.toml, so a config that
carries them did nothing on those releases and changes behaviour on Meta 0.9.
Review them before upgrading.
-
model_fallback(on a profile or under[runtime]) now configures the model fallback chain. MobKit 0.8.33 and earlier ignored it. An unknown key inside it, or an invalid chain, refuses the definition withinvalid_model_fallback. -
tools.denynow denies the listed tools to the profile’s members. MobKit 0.8.45 and earlier ignored it. A name outside the known tool vocabularies fails the member build (DeclaredToolUnknown), and an empty or whitespace entry refuses the definition:
divergent, naming for example
profiles.<name>.tools.deny or profiles.<name>.model_fallback. Resuming
never applies them.
Check before adopting. Give the adoption the definition the installation
boots with (mob.toml, or definition.json):
--json, each store’s keys are listed under ignored_keys (manifest,
mob_id, source, created_by, keys, acknowledged). A --mob-config
that does not parse, or a mob.toml that declares a [self_hosted] or
[realm] table, is refused before planning, naming the file.
Do: for each named key, choose one:
- Remove it to keep the behaviour the store has run with. The store then resumes unchanged.
- Keep it: rerun with
--acknowledge-ignored-keys, which adopts and reports the keys as acknowledged, then advance the stored definition once with the one-shot mob definition update. Until then an authoritative resume that keeps them refuses asdivergent.
5. Keys that only warn: safe to remove
You see in the gateway log:MobDefinition::parse_toml, the diagnostic:
tools.mob_tasks is common in configs written for earlier releases; any
unknown key under [profiles.<name>] or its tools table warns the same way.
Do: remove the key. It is safe on a persistent store: the key never
reaches the parsed definition, so it is not part of the composition Meta
records and compares on resume. Removing or adding it never makes the store
refuse as divergent, and a divergence refusal names only keys the definition
accepts.
6. Empty access and gating paths
You see: an emptyruntime_options.access_config_path or
runtime_options.gating_config_path refuses rpc_gateway init, and the SDK
builders throw on an empty path before they launch it:
null. With the Python
or TypeScript SDK, do not call gating(...) or accessControl(...) /
access_control(...), and keep nothing at config/gating.toml or
config/access.toml under the working directory: the builders load those
files when they are present. See Gating and
Access control.