pub struct MemConfig {Show 21 fields
pub format: Option<u32>,
pub name: Option<String>,
pub version: Option<Version>,
pub description: Option<String>,
pub title: Option<String>,
pub subject: Option<MemSubject>,
pub authors: Option<Vec<String>>,
pub process_mem: Option<String>,
pub schema: Option<SchemaRef>,
pub write_guidance: HashMap<String, Value>,
pub rules: Option<Value>,
pub publish: Option<PublishConfig>,
pub language: Option<String>,
pub read_mems: BTreeMap<String, ReadMemSpec>,
pub community: Option<CommunityOverride>,
pub vcs: Option<VcsConfig>,
pub unregistered_at: Option<String>,
pub sync_state: BTreeMap<String, String>,
pub review_mark: Option<String>,
pub mutation_stamp: Option<MutationStamp>,
pub extra: HashMap<String, Value>,
}Expand description
Full mem configuration loaded from .memstead/config.json.
Fields§
§format: Option<u32>Workspace mem-config format version. Absent means version 1 — the
healthy common case; real mems carry no key — and an unknown value
REFUSES at parse, matching every sibling store (the binding record,
WorkspaceConfig, the anchors sidecar). Until 2026-08-28 this field
was not modeled at all, so serde silently dropped whatever value a
config carried and "format": 99 verified clean. Distinct from
PUBLISHED_MEM_FORMAT, the sealed-archive config’s own version
line with its own gate. Read through Self::format_version.
name: Option<String>Optional mem name. The leaf folder name under
__MEMSTEAD:mems/ (and the disk basename on the legacy disk
path) is authoritative; engine-written configs omit this
field. Tolerated on read for pre-cutover configs and for the
PublishedMemConfig conversion path that still requires
an explicit identity (the caller passes the name in when
projecting).
version: Option<Version>Semver version of the mem content. Read at mem-archive export
time so the engine always knows the current version without manual
tracking. Parsed at config load — invalid version strings fail fast
with a source-attributed serde error rather than slipping through to
export (where the issue only surfaces when a downstream loader tries
to resolve a semver::VersionReq against the mem).
description: Option<String>One-line description of the mem, surfaced in mem-archive metadata and UI.
title: Option<String>Human-readable display title. Display text, NOT identity: no
slug grammar, no uniqueness rule — the mem name stays the sole
handle everywhere (paths, grants, namespace patterns, cross-mem
references, archive filenames). Surfaces that print a mem
prefer this and fall back to the name. Published in
PublishedMemConfig.
subject: Option<MemSubject>The mem’s subject — scope, method, deliberate exclusions. Published verbatim; clears as a unit.
Optional author attribution, surfaced in mem-archive metadata.
process_mem: Option<String>Declared process-mem pairing (agent-trust plan 14): the name of the mem holding this mem’s process tier (verification targets, findings, inquiry entries). Declaration wins over the binding-name derivation the brief renderer and the open-questions health axis otherwise use; a declaration naming an unmounted mem surfaces as a typed health finding, never a silent fallback. Absent means “derive by convention” — the pre-declaration behaviour, unchanged.
schema: Option<SchemaRef>Schema this mem is pinned to. Exact <name>@<version> pin
only — bare-name forms are rejected at config load. Exactly one
schema per mem. The Option keeps serde tolerant so a missing
key surfaces as a structured error from check_config rather
than a deserialize panic; a None value is a validation error.
write_guidance: HashMap<String, Value>Opaque string-map passed through by the engine. Agents and
plugin prompt renderers are free to invent their own keys; the
engine does not parse, validate, or interpret any value inside.
Stripped from PublishedMemConfig — guidance is workspace-
local authorship metadata, not part of the published identity.
Pre-2026-04-24 this field was Option<Value>; the workspace
rewrite normalised it to a map so the shape on
the wire is stable and the engine’s pass-through guarantee is
type-checked.
rules: Option<Value>§publish: Option<PublishConfig>§language: Option<String>§read_mems: BTreeMap<String, ReadMemSpec>Legacy since 2026-08. A read-only sealed-archive mem attaches
to the WORKSPACE mount roster (.memstead/state/mounts.json), not
to a host mem’s config. Nothing writes this field any more; it
survives on the struct so the one-way boot migration
(migrate_legacy_read_mems) can recognise a pre-cutover
registration, turn it into a mount, and strip the key. An empty or
omitted map is the healthy state.
Key is the mem name (matching the archive’s config name).
BTreeMap (not HashMap) so iteration and serialization order
are stable — reproducible log output and diff-friendly config on
disk. Explicit rename = "readMems" documents the on-disk name
at the field (the struct-level rename_all = "camelCase" already
handles it, but explicit rename is greppable from either side).
community: Option<CommunityOverride>§vcs: Option<VcsConfig>Optional VCS layout override. When absent, memstead-git-branch resolves
the default at init time: .git/ at mem root with . as
worktree. When present, gitdir and worktree are paths
relative to the mem root. Stripped from PublishedMemConfig
— VCS layout is workspace-local mechanics, not part of the
published mem’s identity.
Deserialization is tolerant of legacy non-object values (e.g.
"vcs": "system" — the sentinel an older macOS Mem-mode
UI wrote): any non-object form deserializes to None and falls
back to the default-resolution path. The object form is validated
strictly.
unregistered_at: Option<String>Tombstone marker written by memstead mem unregister. ISO-8601
UTC timestamp (YYYY-MM-DDTHH:MM:SSZ) recorded at the moment
the mem was unregistered while its storage was preserved.
When memstead mem init <same-name>
probes the storage and finds an unregistered_at value, it
treats the residue as deliberate operator state and defaults
to the Reattach recovery action (adopting the preserved
entities and clearing the tombstone). Absence (None) on
otherwise-present residue triggers MEM_STORAGE_RESIDUE_DETECTED
unless the caller passes an explicit recovery flag. Stripped
from PublishedMemConfig — tombstones are workspace-local
lifecycle state, not part of the published mem’s identity.
sync_state: BTreeMap<String, String>Per-source “last successfully synced source state”, written by
the ingest layer and surfaced verbatim on the workspace dump.
The engine never parses, validates, or interprets a value:
each token is opaque, its meaning owned by the medium-type
layer that produced it (git → commit id, graph → snapshot
token, filesystem → a small stat digest the plugin
JSON-stringifies). The key is likewise opaque — the binding
layer keys per (binding, facet) (conventionally
"<binding-id>/<facet>#synced", D4), but the engine treats it as
an arbitrary string. This is the durable, shared baseline against which a
fresh ingest iteration diffs “what changed since last time”;
it survives a skill-cache wipe and a machine change because it
lives in engine-held mem config, not ephemeral plugin cache.
Stripped from PublishedMemConfig — sync state is
workspace-local ingest bookkeeping, not part of a published
mem’s identity. BTreeMap (not HashMap) for stable
serialization order: diff-friendly config on disk and
reproducible dump output.
review_mark: Option<String>The mem’s review mark: the last human-approved state, in the
backend-opaque cursor vocabulary changes_since consumes
(git-branch: commit SHA; folder: changelog RFC3339 timestamp).
Absent is a first-class state — a mem with no mark is ordinary,
never an error, and marks never gate writes. One mark per mem;
wire key reviewMark (camelCase per the config’s convention).
Stripped from PublishedMemConfig (allowlist projection) —
review state is workspace-collaboration bookkeeping, not part
of a published mem’s identity.
mutation_stamp: Option<MutationStamp>Engine-owned version stamp of the last successful mutation:
which engine version and which resolved schema performed it.
Written by the engine after a mutation and only when the values
changed (a binary upgrade or a schema repin), never by authors,
never on read-only loads — a boot writes nothing. Boot compares
the running binary against the stamp and surfaces a divergence
as the warn-tier ENGINE_VERSION_SKEW hint; absence of a stamp
is a first-class state (pre-stamp mems), never skew. The stamp
is the substrate any future migration machinery would consult —
deliberately built without that machinery.
Stripped from PublishedMemConfig (allowlist projection) —
workspace-local engine bookkeeping, not published identity.
Wire key mutationStamp (camelCase per the config convention).
extra: HashMap<String, Value>Extra fields not in the known set (captured for round-tripping).
Historical tombstones:
defaultSchema(pre-2026-04): legacy per-mem default type. Per-entitytype:frontmatter is authoritative now.types: [...](pre-schema-artifact, 2026-04): replaced byschema: "<name>@<version>". Legacy entries are hard-rejected bycheck_config.
Implementations§
Source§impl MemConfig
impl MemConfig
Sourcepub fn format_version(&self) -> u32
pub fn format_version(&self) -> u32
The effective config format version: the declared value, or
MEM_CONFIG_FORMAT when the key is absent.