Skip to content

Binding format

A binding (stored as a projection file at .memstead/projections/<mem>/<name>.json) is one versioned record per source→mem obligation: the declaration plus an operations { build, sync, verify } block. It collapses the retired projection + ingest pair into a single file.

This page is generated from the v1 binding JSON Schema and the engine’s medium-capability matrix. Do not edit it by hand — regenerate with cargo run -p xtask -- generate-docs.

FieldTypeRequiredAllowed valuesDescription
versionintegeryes2Binding format version. v2 bindings carry the integer 2; a file without it (or with a prior version) is quarantined by the loader as a retired format and is re-authored with memstead projection init.
intentstringnoWhat the binding is trying to accomplish — prose for the agent. Optional. An all-caps token of three or more characters is read as a relationship of the destination mem’s schema: one the schema does not declare is a BINDING_INTENT_UNKNOWN_RELATIONSHIP finding on every brief and on the verify report, and projection init / projection edit refuse to write such an intent. File names (CLAUDE.md) and protocol or format acronyms (HTTP, JSON) read as prose.
reference_memsarraynoRead-only reference mems (by name) that supply cross-mem context.
destination_memstringyesThe mem this binding writes into.
deny_pathsarraynoPaths excluded from the binding’s scope (workspace-relative globs). Strategy-invariant — moved up from the per-ingest record. A glob deny list is legal only over a path-shaped medium namespace (codebase / filesystem / git); the engine refuses it at binding-validation time over a graph or web medium.
coverage_semanticsstringnoexhaustive, curatedWhether the binding claims to cover everything in its declared scope (exhaustive) or a deliberately partial slice (curated). Optional: absent means NOT STATED — the effective value is resolved per medium (all sources on enumerable media → exhaustive; at least one non-enumerable source, e.g. web → curated). A declared exhaustive over a non-enumerable source is refused at binding validation with curated as the remedy.
rulesobjectnoFree-form binding rules (e.g. a one-shot lens routing string). Opaque to the engine — consumed only by the one-shot brief renderer.
pruneobjectnoPrune policy — additive, optional. Absent means prune is disabled (no deletion proposals). Present (an empty object) means prune produces deletion proposals in the sync brief: the source no longer holds the artifacts an entity describes, both sides are shown, and the agent acting on the brief decides. Prune has no independent schedule (it rides the sync brief, so it carries no trigger/batch_size) and no guarantee level: a source artifact and the entity about it share no merge base, so there is nothing for the engine to decide on the entity’s behalf. The retired guarantee key of earlier records is ignored on read.
operationsobjectyesThe operations this binding declares. Every operation is optional; an absent mutating operation (build/sync) refuses at run time with a remedy, an absent verify means engine defaults.
sourcesarraynoThe inline sources the binding consumes, in declaration order. Each name is unique within the record.

One inline source — the full description of a body of information the pipeline reads: the medium half (type / pointer / change_detection) and the facet half (scope / engagement / preparation).

FieldTypeRequiredAllowed valuesDescription
namestringyesStable name — keys per-source sync/verify state (<mem>/<binding>/<source>#synced).
typestringyescodebase, filesystem, graph, git, webWhat kind of surface this source references.
pointerstringyesWhere the body of information lives — a path, URL, or mem id, interpreted per type.
change_detectionstringnonone, git, mtime, autoOptional declared change-detection strategy: none / git / mtime / auto. Unset means auto (the engine probes for a git work tree). A graph-typed source always uses the graph snapshot signal.
scopearraynoAllow/deny selection over the source. Patterns are SOURCE-relative: each resolves against this source’s pointer, so a scope is written as the paths beneath the pointer, exactly as the rendered brief presents them (deny_paths at the binding level are workspace-relative instead — they span every source, so they have no single pointer). A source with no allow patterns is unscoped — a typed refusal at run time, not “everything”; a source that truly wants everything writes **/*. A pattern that will not compile as a glob is refused at binding validation, naming it.
engagementobjectnoEngagement contract — verbs, tools, terminology, discipline. Free-form; the engine does not interpret it.
preparationstringnoOptional preparation identifier: one registered in the engine’s preparation registry (today entity-load-bearing for graph sources, where an entity anchor’s prepared form is the type’s load-bearing sections, dated-entries for path-shaped sources, where a file of dated entries is delivered as units <path>#<stamp> in stamp order, and code-map for code sources, where a file anchor hashes the file’s interface digest and a tree anchor the code map of the scoped files under it). At most one per source. An identifier the registry does not know is refused at validation time; a registered one over a medium whose anchor namespace admits none of its grains is refused too.

preparation names a preparation the engine registers; an identifier outside this table is refused at binding validation (and a hand-edited record carrying one is skipped at run time, the registered set named). A registered preparation is legal only over a medium whose anchor namespace admits one of its grains. The engine consults the registry at two touchpoints: anchor observation (the prepared form an artifact hashes as — shared by the binding-backed verify and the standalone verify-anchors, so both inherit every entry) and ingest delivery (a source’s unit sequence: one file can carry many units addressed <path>#<key>, delivered in a total order derived from the units’ own keys, identical on every pass; the build operation’s batch_size bounds how many not-yet-disposed units a pass presents). Non-text media conversion (PDF, DOCX, audio) is a non-goal: an agent’s read tool extracts, and the prepared-content hash already drift-detects binary artifacts by raw bytes.

IdentifierTouchpointGrainsWhat it prepares
entity-load-bearinganchor observation (prepared form)entityan entity’s prepared form is the stable serialization of its type’s load-bearing sections (explicitly declared, else the required sections, else every section) — notes-only edits keep dependents’ anchors resolving
dated-entriesingest delivery (unit sequence)spana file is a sequence of entries opening with an ISO date or date-time; each entry is one delivery unit <path>#<stamp>, and a source’s units deliver in stamp order, identical on every pass — a chronological corpus (logs, transcripts, journals, mail threads) is never shuffled
code-mapanchor observation (prepared form)file, span, treea scoped code file’s prepared form is its interface digest (imports, exports, declarations and their signatures; comments, formatting and bodies invisible), and a tree’s is the digest of every scoped file under it — an anchor drifts when an interface changes and stays quiet when only an implementation does
quoted-phraseanchor observation (prepared form)span, url, entityan artifact <path-or-url-or-entity>#<phrase> addresses the occurrence of a literal phrase in a text and its prepared form is the phrase itself — the anchor resolves while the file, the observed page or the entity still says those words and reads orphaned once they are gone, whatever else changed

Each operation under operations is optional. An absent build or sync makes that mutating operation refuse at run time with a projection enable <op> remedy; an absent verify means engine defaults (verify never refuses on an absent operation block). Verify mutates no entity: a completed run records its findings store, which is the verify surface’s own state outside the mem, and backfills observed hashes onto hash-less anchors, which is measurement machinery. Its one write into the mem’s own config, the #verified freshness baseline, rides projection verify --advance, so a gate or a grader that verifies in order to read leaves that config byte-identical.

The build operation — the only operation carrying a mode. Grows new coverage (discovery) or runs a single bounded pass (one-shot). trigger / batch_size / post_actions are scheduling attributes.

FieldTypeRequiredAllowed valuesDescription
batch_sizeintegeryes≥ 1How many artifacts a single run processes.
modestringyesdiscovery, one-shotdiscovery builds out new coverage; one-shot runs a single bounded pass. The retired refinement value is not accepted.
post_actionsobjectnoFree-form post-run actions (e.g. a one-shot archive_source flag). Opaque to the engine — consumed only by the one-shot brief renderer.
triggerstringyesloop, manual, on-eventWhat sets an operation running. loop runs continuously under /loop; manual runs only when invoked; on-event is reserved for event-driven hooks.

The sync operation — the sole maintenance writer. Carries no mode. An absent sync block makes that mutating operation refuse at run time.

FieldTypeRequiredAllowed valuesDescription
batch_sizeintegeryes≥ 1How many artifacts a single run processes.
triggerstringyesloop, manual, on-eventWhat sets an operation running. loop runs continuously under /loop; manual runs only when invoked; on-event is reserved for event-driven hooks.

The verify operation — measurement. Mutates no entity: it records findings into the verify surface’s own store and backfills observed anchor hashes (measurement machinery). The #verified freshness baseline, its one write into the mem’s config, moves only under projection verify --advance. Carries no mode. adjudication_cap and full_resync_every are additive tier-3 scheduling knobs that default to the engine’s built-in values when absent.

FieldTypeRequiredAllowed valuesDescription
adjudication_capintegerno≥ 0The maximum number of hash-drift adjudications a single verify run asserts before queueing the remainder as backlog. 0 disables the cap.
batch_sizeintegeryes≥ 1How many artifacts a single run processes.
full_resync_everyintegerno≥ 0Every N verify runs, a full-enumeration coverage sweep runs (for enumerable mediums). 0 disables scheduled full walks.
triggerstringyesloop, manual, on-eventWhat sets an operation running. loop runs continuously under /loop; manual runs only when invoked; on-event is reserved for event-driven hooks.

Which fields and operations a binding may legally declare depends on the medium its source facets resolve to. The engine derives this from the capability matrix below and refuses an illegal combination at binding-validation time. A scope pattern its medium cannot express is additionally refused when the binding is resolved for a run, because validation reaches only the paths that EDIT a record — a hand-authored or pre-vocabulary binding would otherwise run over a scope that selects nothing.

MediumEnumerableChange signalBase retrievableAnchor namespaceGlob deny_paths
codebaseyesyesyespathyes
filesystemyesyesyespathyes
gityesyesyespath+commityes
graphyesyesyesentityno
webnononourlno
  • Glob deny_paths are legal only over a path-shaped namespace — declaring them over a medium whose Glob deny_paths column is no is refused at binding validation.
  • Base retrievable states whether the medium can hand back a prior version of an artifact; it is a fact about the source the fidelity report restates per facet. Nothing gates on it: prune produces proposals only and never merges.
  • graph scope is an entity selector, not a path glob. A graph source selects entities, so its scope patterns are * (the whole mem), type:<entity_type>, or id:<glob> over the full mem--slug id. A path-shaped pattern is refused — at binding validation and again when the binding is resolved for a run — rather than accepted and ignored — scope that selects nothing while looking like selection is the failure this rule prevents. The columns describe the medium’s declared capability, not the current state of every operation over it.