Skip to main content
Version: Next

Reference

This page summarizes Memzoi v0's public CLI, MCP, and model values.

CLI commands

CommandPurpose
memzoi initInitialize repo .memzoi/ memory and local runtime state.
memzoi proposePropose a new memory record. Built-in default auto-approves valid proposals but does not apply them.
memzoi proposalsList, show, and bulk-apply proposal inbox state.
memzoi proposal-filesList, show, validate, and apply OKF proposal files under .memzoi/proposals/pending/.
memzoi materializePlan, explicitly decide, and apply one repository-safe candidate as an unstaged canonical Git change; it never stages, commits, pushes, or opens a pull request.
memzoi localAdd, list, and search local-only runtime memory records.
memzoi checkpointAdd and list runtime session checkpoints.
memzoi eventsExport runtime event-log rows.
memzoi session-endPromote explicit structured session-end candidates into proposal files or runtime memory.
memzoi capturePlan evidence-backed capture from one explicit Markdown, instruction, ADR, or Git-change source; record a complete review; and route reviewed candidates.
memzoi maintenanceGenerate an immutable repository-only maintenance plan, or materialize explicitly selected repository actions as one unstaged, reviewable transaction.
memzoi lifecyclePlan, authorize, revoke, inspect, and atomically apply exact owner-authorized private lifecycle actions. This local CLI/core workflow is not exposed through MCP.
memzoi approveApprove a pending or validated memory proposal.
memzoi rejectReject a proposed memory.
memzoi applyApply an approved memory proposal into canonical .memzoi/records/*.md.
memzoi supersedeAtomically supersede an active, non-private repo record with a same-scope repo-safe replacement.
memzoi tombstoneAtomically tombstone an active, non-private repo record.
memzoi searchSearch active, unexpired memory records.
memzoi expiryInspect a record by ID and explain its expiry eligibility without mutating it.
memzoi contextBuild a prompt-ready context pack for a task.
memzoi handoffBuild a compact context pack for switching agents or harnesses.
memzoi precheckCheck planned work against risky memories before acting.
memzoi exportExport active repo memory into reviewable files.
memzoi rebuildRebuild the derived SQLite database from canonical .memzoi/records/ files.
memzoi doctorCheck installation and repo memory readiness.
memzoi eval recallEvaluate a versioned file-native trust corpus in disposable isolated state.
memzoi eval captureEvaluate capture quality, safety, and review burden in disposable isolated state.
memzoi quickstartPrint or run a tiny first-run workflow.
memzoi updateCheck for or apply a Memzoi release update.
memzoi mcpPrint MCP integration configuration.
memzoi integrateGenerate or install agent integration prompts and instructions.

Run memzoi <command> --help for exact options.

Common command options

CommandImportant options
init--force, --json
propose--type, --scope-kind, --visibility, --sensitivity, --source-kind, --source-ref, --title, --body, --actor, --manual, --auto-approve, --apply, --json
proposals list--status open|pending|validated|approved|rejected|applied|all, --json
proposals show<proposal-id>, --json
proposals apply--all-approved, --actor, --json
proposal-files list--json
proposal-files show<proposal-id>, --json
proposal-files validate--json
proposal-files apply<proposal-id>, --actor, --json
proposal-files reject<proposal-id>, --reason, --actor, --json
materialize plan--candidate-file, --output, --json
materialize decide--candidate-file, --plan-file, --decision-at, --output, --json
materialize apply--candidate-file, --plan-file, --decision-file, --candidate-id, --plan-id, --decision-id, --json
local add--type, --title, --body, --actor, --json
local list--json
local search<query>, --limit, --json
checkpoint add--task, --note or --from-file, optional --successor-of, --operation-id, --expected-version, --actor, --json
checkpoint continue<checkpoint-id>, --operation-id, --expected-version, --actor, --json
checkpoint close<checkpoint-id>, --operation-id, --expected-version, --actor, --json
checkpoint list--json
events export--jsonl
session-end--from-file <path> or --from-checkpoint <checkpoint-id>, --operation-id, --expected-version, --actor, --json
capture plan--source <project-relative.md> or --request-file <capture-request.{json,yaml}>, --source-bytes <path|-> for supplied_bytes, --source-id, --output, --json
capture review--plan-file, --decisions-file, --prior-review-file, --source-bytes <path|-> when replaying supplied_bytes, --reviewed-by, --reviewed-at, --output, --json
capture apply--plan-file, --review-file, --prior-review-file, --source-bytes <path|-> when replaying supplied_bytes, --plan-id, --review-id, --actor, --json
maintenance planrepeated --record-id, --evaluated-at <RFC3339>, --output, --json
maintenance materialize--plan-file <path>, --plan-id <id>, repeated --action-id <id>, --decision-at <RFC3339-UTC>, --json
lifecycle planrepeated --record-id, --evaluated-at <RFC3339>, --output, --json
lifecycle authorize--request-file <path>, optional --plan-file <path>, optional --expires-at <RFC3339>, --json
lifecycle revoke--grant-id <id>, --json
lifecycle inspect record<record-id>, --json
lifecycle inspect grant<grant-id>, --json
lifecycle apply--request-file <path>, --grant-id <id>, optional --plan-file <path>, --json
lifecycle maintenance enable--json
lifecycle maintenance disable--json
lifecycle maintenance inspect--json
lifecycle maintenance reconcile--json
approve<proposal-id>, --actor, --json
reject<proposal-id>, --reason, --actor, --json
apply<proposal-id>, --actor, --json
supersede<record-id>, --type, --scope-kind, --visibility, --sensitivity, --source-kind, --source-ref, --title, --body, --actor, --json
tombstone<record-id>, --reason, --actor, --json
search<query>, --scope-kind, --type, --path, --limit, --json
expiry<record-id>, --json
context--task, --path, --token-budget, --include-local, --include-session, --json
handoff--task or --path, --token-budget, --include-local, --include-session, --json
precheck--path, --action, --command, --scope-kind, --json
export<format>, --scope-kind, --json
rebuild--json
doctor--project-root, --json
eval recall--corpus <path>, --baseline <path>, --update-baseline, --json
eval capture--corpus <path>, --baseline <path>, --update-baseline, --json
quickstart--apply-sample, --json
update--check, --ref, --json
mcp config--project-root
integrate list--json
integrate prompt--profile
integrate instructions--profile, --file, --json

Recall evaluation

Run the checked-in trust corpus without opening or mutating the current project's canonical records, proposal inbox, runtime database, exports, or event log:

memzoi eval recall --corpus evals/recall/quality/corpus.yaml --baseline evals/recall/quality/baseline.json
memzoi eval recall --corpus evals/recall/quality/corpus.yaml --baseline evals/recall/quality/baseline.json --json

--baseline is optional. --update-baseline requires it and is the only mode that writes the selected baseline. A threshold-failing run is never written:

memzoi eval recall --corpus evals/recall/quality/corpus.yaml --baseline evals/recall/quality/baseline.json --update-baseline

The explicit corpus is strict YAML with version memzoi-recall-corpus/v2. It references OKF Markdown, proposal, and private runtime fixtures relative to the corpus, fixes the evaluation clock, declares aggregate thresholds, and defines tagged cases. Unknown fields are rejected. The following abridged excerpt shows the search and precheck shapes; a complete v2 trust corpus must also declare proposal/runtime fixtures, context and write-gate cases, and forbidden opportunities for every required safety category:

version: memzoi-recall-corpus/v2
name: project-trust-v2
evaluated_at: 2026-07-10T12:00:00Z
records_root: records
records:
- package-manager.md
- package-manager-warning.md
- unrelated-package-manager.md
thresholds:
min_mean_recall_at_k: 1.0
min_mean_mrr: 1.0
min_precheck_precision: 1.0
min_precheck_recall: 1.0
max_stale_leakage_rate: 0.0
max_expired_leakage_rate: 0.0
max_scope_leakage_rate: 0.0
max_forbidden_hit_rate: 0.0
min_citation_integrity: 1.0
min_provenance_integrity: 1.0
min_case_pass_rate: 1.0
max_estimated_usage: 500 # Per-case maximum; corpus total is reported separately.
# max_p95_latency_ms: 50
cases:
- surface: search
id: package-manager-decision
query: package manager
relevant_ids: [package-manager]
forbidden:
scope: [unrelated-package-manager]
scope_kind: repo
type: decision
lane: semantic
path: package.json
k: 5
- surface: precheck
id: package-manager-precheck
path: package.json
scope_kind: repo
relevant_ids: [package-manager-warning]

Case surface selects one strict shape:

  • search accepts a query, top-k limit, relevant IDs, categorized forbidden IDs, optional scope/type/lane/path filters, and an optional proposal fixture.
  • precheck accepts path/action/command inputs, scope, and expected warning IDs.
  • context accepts task/path/budget inputs, local/session opt-ins, and expected included or forbidden destinations.
  • write_gate declares a prohibited candidate, expected policy issue code, and a record ID that must remain absent.

JSON output uses memzoi-recall-report/v2. Its definitions object explains the versioned formulas, while runtime reports the Memzoi/SQLite environment, timer, isolated-state guarantee, and estimator. metrics contains:

  • search case count, mean recall at k, and mean MRR;
  • micro precheck precision/recall with true-positive, false-positive, and false-negative counts;
  • stale, expired, scope, prohibited, destination, and total forbidden leakage as hits, opportunities, and rates;
  • citation and provenance integrity as valid/checked ratios;
  • deterministic approx_words usage totals and distribution;
  • nearest-rank p50/p95 monotonic-clock latency; and
  • the overall case pass ratio.

Empty precision/recall/integrity denominators resolve to 1.0; empty leakage denominators resolve to 0.0. Threshold comparisons use the underlying values, not their display rounding.

The typed memzoi-recall-baseline/v1 artifact contains only deterministic metrics and per-case outcomes. Runtime metadata and observed latency are not exact-compared. A baseline comparison has status match, changed, or incompatible: deterministic changes are reported for review but remain informational, while an incompatible corpus/schema identity fails the report. Corpus thresholds remain the regression gate. A valid corpus prints its full report before a threshold or baseline failure returns non-zero; corpus or fixture validation errors return non-zero without a report.

Capture evaluation

Run the checked-in capture quality gate from isolated temporary projects:

memzoi eval capture \
--corpus evals/capture/corpus.yaml \
--baseline evals/capture/baseline.json

memzoi eval capture \
--corpus evals/capture/corpus.yaml \
--baseline evals/capture/baseline.json \
--json

The strict memzoi-capture-corpus/v1 YAML names every required extractor profile, explicit source fixture, expected candidate and exact evidence span, classification, routing action, forbidden candidate, review outcome, and optional stale-source check. Unknown fields, escaping fixture paths, duplicate IDs, invalid expectations, and unaccounted profiles are rejected.

The memzoi-capture-report/v1 report contains aggregate and per-profile candidate precision/recall, evidence validity, destination/sensitivity/action accuracy, forbidden-hit rate, unsupported-outcome accuracy, review-burden counts, payload observations, and p50/p95 latency. Its non-waivable hard gates require deterministic no-write planning, valid evidence from named sources, no unnamed evidence or undeclared policy reads, no prohibited-content echo, stale-source identity rejection, and execution of every required profile.

--baseline is optional. When present, capture requires an exact match with the typed memzoi-capture-baseline/v1 deterministic projection; unlike observed latency and payload metadata, any changed deterministic metric, profile fingerprint, hard gate, or case outcome fails. Update an accepted change only after every gate passes:

memzoi eval capture \
--corpus evals/capture/corpus.yaml \
--baseline evals/capture/baseline.json \
--update-baseline

See the evaluation contributor guide for metric definitions and fixture guidance.

Repository maintenance planning

memzoi maintenance plan reads admitted canonical repository records directly and emits an immutable memzoi/maintenance-plan evidence artifact. It reports exact duplicates, conservative high-confidence contradictions, staleness, expiry, renewal candidates, and typed action candidates. These are reviewable findings, not execution authority: the planning command never mutates a record, proposal, index, private runtime row, overlay, WAL/event log, or Git state.

memzoi maintenance plan \
--evaluated-at 2026-07-18T12:00:00Z \
--json

memzoi maintenance plan \
--record-id maintenance-plans-separate-evidence-from-execution-authority \
--output /path/outside/the/worktree/maintenance-plan.json

Omit --record-id to evaluate every admitted repository record. Repeating the option narrows the targets while retaining their comparison neighbourhood. Omit --evaluated-at to capture the system clock once; supplying it supports byte-identical replay against the same snapshot and policy.

Planning scans at most 10,000 filesystem entries but admits at most 256 canonical records. The limits are deliberately separate: the inventory ceiling bounds traversal, while the admitted-record ceiling bounds synchronous per-record Git review checks, pairwise detector work, and the serialized artifact (just under 2 MiB). Planning fails closed when any repository-inventory, per-file, aggregate-input, work, diagnostic, or artifact limit is exceeded.

Without --json, stdout contains only the plan identity, validity timestamps, and aggregate counts. --json emits the complete repository-safe artifact. --output atomically creates the same pretty JSON without replacing an existing file. Its parent must already be a real directory, and the destination must be outside the Git worktree and all Memzoi-managed runtime roots.

The artifact schema contains separate repository materialization, private derived-state, and owner-authorized private action groups for downstream work. memzoi maintenance materialize accepts only explicit action IDs from the repository-materialization group. Private planning and owner-authorized execution use the separate local memzoi lifecycle CLI/core workflow; MCP plan_maintenance never exposes private records or lifecycle mutation.

Materialization requires one current immutable plan, its exact plan ID, at least one explicitly selected action ID, and a canonical UTC decision time:

memzoi maintenance materialize \
--plan-file /path/outside/the/worktree/maintenance-plan.json \
--plan-id "$(jq -r .plan_id /path/outside/the/worktree/maintenance-plan.json)" \
--action-id ACTION_ID \
--decision-at 2026-07-20T12:00:00Z \
--json

The command supports exact duplicate consolidation and renewal successors. It projects every final OKF byte before authorizing one complete maintenance batch, then installs all changed paths through a durable journal with exact backups and disposable-index reconciliation. Exact reruns return already_current, even after plan expiry. Fresh writes require a currently valid plan and clean selected Git targets. Outputs remain unstaged; Memzoi returns narrow structured git diff commands but never stages, commits, pushes, changes Git configuration, or opens a pull request. MCP remains planning-only.

The exact current maintenance artifact schemas are memzoi/maintenance-request and memzoi/maintenance-plan; the plan schema is the sole plan-format identity, and maintenance-policy/1 identifies policy behavior. The current schema includes canonical pairwise contradiction edges. Memzoi is pre-1.0 and current-schema-only: artifacts that do not match the current schema are rejected and must be regenerated. There is no compatibility reader, schema fallback, deprecated field alias, or SQLite migration. An old runtime database must be manually upgraded or removed before these commands can open it.

Owner-authorized private lifecycle

Private lifecycle work is local CLI/core only and follows plan → exact owner request → one-shot grant → atomic apply → idempotent result:

Separately, memzoi lifecycle maintenance enable|disable|inspect|reconcile manages standing authority for derived automatic-recall suppression. The projection is rebuildable and content-free, has explicit disabled|current|dirty|blocked state, and fails automatic private recall closed unless it is disabled or current for the authoritative generation. Inspection reports an otherwise-current projection as stale at its persisted not_after; audited private reads reconcile it before recall, while immutable reads remain non-mutating and fail closed. This authority never reuses an owner_action_grant and never resolves a contradiction or selects a winner.

Start by inspecting the target. This shell-safe template uses a quoted variable instead of angle-bracket syntax that a shell would interpret as redirection:

RECORD_ID='replace-with-private-record-id'

memzoi lifecycle inspect record "$RECORD_ID" --json

For a plan-bound request, create fresh evidence before constructing the exact owner request:

memzoi lifecycle plan \
--record-id "$RECORD_ID" \
--output /private/review/lifecycle-plan.json \
--json

The direct request walkthrough below is separate and does not bind that optional plan. Optional --evaluated-at and --expires-at overrides are deliberately omitted so copied examples cannot become stale.

The strict request schema is memzoi/private-lifecycle-request:

The following JSON is an illustrative, non-executable shape template. Replace the record ID and version with values from inspection, select the exact owner action, and recompute request_id; placeholder text is never accepted as authority.

{
"schema": "memzoi/private-lifecycle-request",
"request_id": "blake3:<computed-64-lowercase-hex-digest>",
"operation_id": "owner-operation-42",
"source": { "kind": "direct" },
"actions": [
{
"kind": "pin",
"record_id": "local-<opaque-uuid>",
"expected_version": "0123456789abcdef0123456789abcdef"
}
]
}

A planned request instead uses {"kind":"maintenance_plan","plan_id":"...","selected_action_ids":["..."]}. For that source, pass the exact selected plan artifact to both authorize and apply. The direct walkthrough below intentionally omits --plan-file. The request_id is recomputed from the schema, caller-controlled operation_id, source, and exact ordered action payloads; a mismatch is rejected. Core callers should use PrivateLifecycleRequest::with_computed_id; its identity is the BLAKE3 digest of the NUL-terminated memzoi/private-lifecycle-request-id/v1 domain separator followed by canonical JSON containing only schema, operation_id, source, and actions. Do not hand-edit a previously computed ID after changing an action.

Requests contain one to 64 actions, at most 256 distinct mutation targets, no duplicate or overlapping participation, and exact version tokens for every target and evidence reference. Reason codes are nonempty machine-readable values of at most 128 UTF-8 bytes. Inputs may be strict JSON or YAML, but must be regular non-symlink files no larger than 2 MiB; unknown or duplicate keys, trailing documents, special files, and truncation are rejected.

After constructing and reviewing the exact request artifact, authorize and apply it. Copy the returned grant_id into the quoted shell variable before continuing:

memzoi lifecycle authorize \
--request-file /private/review/lifecycle-request.json \
--json

GRANT_ID='replace-with-grant-id-from-authorize'

memzoi lifecycle inspect grant "$GRANT_ID" --json

memzoi lifecycle apply \
--request-file /private/review/lifecycle-request.json \
--grant-id "$GRANT_ID" \
--json

To cancel an active grant instead of applying it:

memzoi lifecycle revoke --grant-id "$GRANT_ID" --json

plan and both inspect forms are strictly read-only. authorize may create only one authoritative owner_action_grant row, and revoke may update only that grant store. apply is the only command that may change private record content/status, lifecycle state or relations, ordinary-read eligibility, application receipts, or lifecycle audit events.

Platform boundary: In this release, the artifact-backed lifecycle authorize and lifecycle apply CLI commands are Unix-only because their required request artifact—and optional plan artifact—must be opened using fail-closed regular-file, no-symlink semantics. lifecycle plan --output is also Unix-only because private plans use an atomic no-clobber installer. On non-Unix systems these paths fail before any lifecycle write. lifecycle plan without --output, both lifecycle inspect commands, and lifecycle revoke remain available.

Tagged actions are extend_automatic_recall, extend_validity, retain_until, pin, unpin, renew_from_evidence, correct, supersede, consolidate, resolve_contradiction, quarantine, and release_quarantine. Duplicate detection and contradiction detection supply member sets only: the owner request must name the keeper or winner. See Exact owner-authorized private lifecycle for the per-action lane, clock, evidence, compatibility, and retention rules.

Authorization time always comes from the service clock. --expires-at may only shorten the effective expiry, which is the earliest of authorization plus 24 hours, the requested expiry, and a selected maintenance plan's not_after. The stored grant row is authoritative; copied JSON cannot bypass expiry, revocation, consumption, exact request binding, or database revalidation. Authorizing an identical request reuses an identical active grant. Revoking an active grant returns revoked; an already revoked or consumed grant returns a typed no-op, while an unknown grant fails without writes.

Apply checks operation replay/conflict first, then revalidates the grant, request, optional plan, policy, comparison neighbourhood, lane constraints, and every target/evidence version under the lifecycle lock and one shared SQLite transaction. The whole action group and exactly one grant consumption commit together or all lifecycle writes roll back. The same operation_id, request_id, and recorded grant_id returns the recorded result after mirror convergence. A different grant is a zero-write replay mismatch; the same operation with another request is a zero-write operation-ID conflict.

Each successful lifecycle commit advances the authoritative shared.db lifecycle generation. A worktree mirror must converge to that generation before it can serve an ordinary read; refresh failure returns a safe mirror-refresh-required error. Grants and application receipts remain only in shared authority. Audit events contain no private content, evidence IDs/text, provenance payloads, request digests, content hashes, or content-derived versions.

Private --output plans use atomic no-clobber installation under a real existing directory and must remain outside both the Git worktree and all Memzoi-managed runtime directories. MCP exposes no corresponding lifecycle tool and its plan_maintenance capability remains repository-only.

Evidence-backed capture

Capture turns one explicitly named project source into evidence-linked memory candidates without ambient repository scanning or inference from chat, shell history, or hidden agent state. The convenience --source form selects the markdown-deterministic profile; --request-file accepts the complete strict JSON or YAML request needed by instruction, ADR, and Git-change profiles. Its three CLI stages keep extraction, human judgment, and writes separate:

memzoi capture plan \
--source notes/session-findings.md \
--source-id session-findings \
--output capture-plan.json \
--json

memzoi capture review \
--plan-file capture-plan.json \
--decisions-file capture-decisions.json \
--reviewed-by zoki \
--reviewed-at 2026-07-10T12:00:00Z \
--output capture-review.json \
--json

memzoi capture apply \
--plan-file capture-plan.json \
--review-file capture-review.json \
--plan-id capture_... \
--review-id review_... \
--actor zoki \
--json

plan and review do not write memory state. --output optionally writes the complete JSON artifact, while --json prints it; without --json, the command prints a human-readable view. Request, plan, decision, and review artifacts must be regular, nonsymlink UTF-8 files no larger than 2 MiB. Artifact output is installed without replacing an existing path. The artifact's data class also constrains where it may be saved, as described below.

Deterministic Markdown profile

The markdown-deterministic profile accepts exactly one regular UTF-8 .md file named by a POSIX project-relative path. Absolute paths, traversal components, backslashes, .memzoi, symbolic links, non-Markdown files, and files larger than 1 MiB are rejected. The source is read only from the current project; capture never searches for additional inputs. The profile also caps a plan at 100 candidates, 4,096 Markdown headings, 16 KiB per evidence item, 256 KiB of total evidence, a bounded 10,000-file/32 MiB duplicate inventory, and a serialized plan just under 2 MiB. The extractor profile is markdown-deterministic. Plans identify the concrete extractor as id: memzoi-markdown, together with its version and configuration hash.

Capture file access and private artifact saving currently require Unix handle-relative, no-symlink primitives. Windows builds fail these capture operations closed; the rest of the CLI remains available there.

The extractor recognizes ATX headings outside fenced code blocks. A heading prefix determines the type, lane, destination, and sensitivity of the section that follows it:

Heading prefixType and lanePlanned route
Fact:fact, semanticRepo-safe pending proposal
Decision:decision, semanticRepo-safe pending proposal
Procedure:procedure, proceduralRepo-safe pending proposal
Warning:warning, semanticRepo-safe pending proposal
Failed attempt:failed_attempt, episodicRepo-safe pending proposal
Risk:risk, semanticRepo-safe pending proposal
Preference:preference, semanticLocal-only runtime record
Episode:episode, sessionTemporary session runtime record

For example:

## Decision: Verify downloaded release archives

Verify the SHA-256 checksum before extracting a release archive.

Each candidate contains the exact source locator, source and evidence hashes, byte and line spans, heading kind, extractor identity, and deterministic claim/candidate identities. Planning also compares candidates with canonical records, pending proposals, active runtime memory, and earlier candidates in the same source. Exact matches become no-write duplicates; same-scope, same-title disagreements become conflicts requiring lifecycle resolution. A document without a recognized typed heading becomes needs_review with unknown sensitivity rather than being silently routed. In a mixed document, nonempty preamble text and untyped sections produce identity-covered unsupported_markdown_content diagnostics with their source ID and starting line, so typed extraction cannot silently hide unsupported regions.

The same source bytes and relevant memory inventory produce the same plan. The plan_id pins the request, source snapshot, extracted candidates, duplicate/conflict match sets, reserved proposal IDs, policy/configuration versions, and preconditions. Planning opens existing runtime inventory read-only and does not create or change .memzoi/, SQLite, proposal, export, or event state. If runtime inventory is missing or cannot be read safely, affected local/session candidates become needs_review no-write actions with a stable warning. Unaffected repo-only candidates retain the same identity they would have against an empty runtime inventory.

Instruction, ADR, and Git-change profiles

Extension profiles use a complete memzoi/capture-request artifact. For example, this request captures one explicitly named agent instruction file:

schema: memzoi/capture-request
sources:
- source_id: agent-rules
locator:
kind: project_path
path: AGENTS.md
media_type: text/markdown
extractor:
profile: instruction-deterministic
memzoi capture plan --request-file capture-request.yaml --output capture-plan.json --json

The profiles and accepted source shapes are closed sets:

ProfileAccepted explicit sourceExtraction and routing boundary
instruction-deterministicOne project_path whose basename is AGENTS.md or CLAUDE.mdPreamble and nonempty sections become scoped procedures by default; typed headings retain their typed memory mapping. A nested instruction file scopes candidates to its parent directory. Memzoi-generated marker blocks and whole generated projections are excluded. Temporary, session, WIP, scratch, personal, private, or local-only markers in headings, preambles, or section bodies become needs_review with unknown sensitivity.
adr-deterministicOne Markdown project_path, or one project_directory with ignore_policy: git-v1 and include: ["*.md"]Recognizes ADR context, decision, consequences, risk, and supersession fields. Accepted/adopted/approved ADR fields may route repo-safe, except supersession always requires lifecycle review. Draft, rejected, superseded, deprecated, or unknown status remains needs_review.
git-change-deterministicOne .diff/.patch project_path plus explicit Git context, one supplied_bytes descriptor plus explicit Git context and transport bytes, or one immutable git_rangeParses strict unified Git diffs and extracts typed added Decision, Procedure, Warning, Risk, and Failed attempt sections. Typed deleted guidance is preserved as an old-side needs_review candidate and cannot route directly to repo memory. Evidence records revisions, blobs, old/new paths, change kind, hunk identity, side, and line coordinates. Unsupported additions and rename-only changes produce diagnostics instead of speculative memory.

ADR directory capture sorts a bounded set of Markdown members, follows the repository's .gitignore policy, never enters .git or .memzoi, and snapshots both member content and ignore-policy inputs. Its locator shape is:

locator:
kind: project_directory
path: docs/adr
recursive: true
ignore_policy: git-v1
include: ["*.md"]

Git-change sources never infer revision identity from ambient HEAD. Git range rendering requires Git 2.43 or newer and is capped at 512 changed files and 4,096 diff hunks. A project diff names git.repository, git.base, and git.head; a git_range instead carries repository, full base/head object IDs, merge_parent (base_to_head or first_parent), rename_detection, and diff_format: git-unified-v1 inside the locator. The range loader resolves and pins commit objects, runs a bounded deterministic local Git diff with quoted paths and attributes pinned, and does not change the worktree, index, refs, or configuration. The bounded local repository configuration is prohibited-scanned, rejects external includes, and is identity-covered; inherited Git tracing and configuration environments are cleared. Applicable .gitignore files are read only from the explicitly named head tree and are likewise prohibited-scanned and identity-covered; project and supplied diff sources do not consult ambient worktree ignore files. Combined and binary diffs, non-regular evidence modes, unsafe paths, and unsupported diff forms fail closed.

A supplied_bytes request additionally pins a safe display name, media_type: text/x-diff, exact byte length, and blake3:<64-lowercase-hex> source content hash. The bytes are transported separately and are never read from ambient stdin. Pass the same exact bytes at all three trust boundaries:

memzoi capture plan \
--request-file supplied-diff-request.yaml \
--source-bytes reviewed.diff \
--output capture-plan.json \
--json

memzoi capture review \
--plan-file capture-plan.json \
--decisions-file capture-decisions.json \
--source-bytes reviewed.diff \
--reviewed-by zoki \
--reviewed-at 2026-07-11T12:00:00Z \
--output capture-review.json \
--json

memzoi capture apply \
--plan-file capture-plan.json \
--review-file capture-review.json \
--source-bytes reviewed.diff \
--plan-id capture_... \
--review-id review_... \
--actor zoki \
--json

Use --source-bytes - only to select stdin explicitly. Missing, extra, changed, oversized, symlinked, or non-regular transport bytes fail before a review or write. Project-path, directory, and Git-range requests reject --source-bytes.

Data classes and review

Every plan and review has one conservative data_class:

  • repo_safe means every routeable candidate is explicitly repo-safe and repo-bound. The artifact may be saved to a normal review location, but never under .memzoi, the private runtime directory, or generated exports.
  • private means the artifact contains or derives from local/session/private or unresolved material. CLI output may be printed, but --output is accepted only under the project's private runtime directory, never under the project root or generated exports.
  • blocked means a prohibited credential, known secret token, private key, private-personal-data, or raw-transcript pattern was found. The redacted plan omits source snapshots, candidates, and evidence text, reports only safe diagnostics, cannot be reviewed, and may only be emitted to standard output.

The strict review-input artifact must decide every candidate exactly once. This JSON example accepts one candidate:

{
"schema": "memzoi/capture-review-input",
"plan_id": "capture_...",
"decisions": [
{
"candidate_id": "candidate_...",
"outcome": "accept"
}
]
}

Outcomes are accept, reject, edit, and defer. Accept keeps a routeable extracted candidate. Reject and defer produce no write. Edit requires a complete replacement memory draft and may request a destination; policy is reapplied to the edited candidate. Duplicates cannot be accepted as new memory, conflicts require separate lifecycle resolution, and a no-write candidate must be edited, rejected, or deferred. reviewed_by must be non-empty and reviewed_at must be an explicit RFC 3339 time. The resulting review_id pins the plan, reviewer, time, complete decision set, and any reviewed candidate edits.

A later review may replace deferred decisions only. Set prior_review_id in the next capture-review-input artifact and pass the complete predecessor with --prior-review-file <capture-review.json>. Core verifies the prior review identity, requires the same plan, preserves every terminal decision byte-for-byte after normalization, and binds the new review ID to its predecessor. Applying that later review also requires the immediate predecessor through capture apply --prior-review-file; apply repeats the lineage validation at the locked transaction boundary. The v0.4 profile supports one predecessor hop. A review whose predecessor already names an earlier review is rejected until a future interface can carry and validate the complete ancestor chain.

Review recomputes the plan before creating an artifact. Apply validates the supplied plan and review identities, reconstructs the review, and recomputes current source/inventory preconditions again before writing and after acquiring the repo lifecycle lock when needed. A changed source, new duplicate/conflict, consumed proposal ID, altered artifact, or mismatched expected ID is a stale zero-write error.

Apply routing and provenance

Only accepted or edited routeable candidates are considered during capture apply:

  • A repo/repo-safe candidate creates a pending OKF packet under .memzoi/proposals/pending/. Capture never writes it directly to .memzoi/records/; validate, review, and explicitly apply that packet with memzoi proposal-files apply <proposal-id>.
  • A local candidate creates a private local runtime record.
  • A session candidate creates a private session runtime record.
  • Rejected, deferred, duplicate, conflicting, blocked, and unresolved candidates write nothing.

Proposal-file and runtime writes are one crash-recoverable guarded operation. A content-free, fsynced journal and a SQLite commit marker let the next service open roll back an interrupted uncommitted batch or finish a committed proposal install without exposing private bodies in the journal. The result uses schema memzoi/capture-apply-result and lists each proposal file or runtime record written.

Capture provenance records the plan/review, original and reviewed candidate identities, extractor, evidence locator/spans/hashes, confidence, destination, sensitivity, and review outcome. Pending proposal packets retain the review evidence. When a proposal is applied, canonical OKF keeps a compact form without copied evidence text; its evidence identity and lineage remain available to rebuild, recall citations, and later audits. Private runtime records retain the same provenance through runtime preservation and rebuild.

MCP exposes only the read-only Markdown/project-path planner as plan_capture; instruction, ADR, directory, supplied-byte, and Git-range requests remain CLI-only and are rejected at the MCP boundary. MCP deliberately exposes no capture review or apply tool and denies private results by default. See MCP and agent integration.

Classified import

The import workflow accepts a compact, explicit manifest. It does not discover or parse agent instruction files, chat transcripts, ADRs, or other source formats, and it does not infer a destination from prose. Each candidate already carries its intended destination and a reason for that classification. The lifecycle policy that governs the destination boundary is documented in Destination classification in the lifecycle policy.

Commands and options

memzoi import plan --from-file <manifest.yml> [--actor cli] [--json]
memzoi import apply --from-file <manifest.yml> --plan-id <import_…> [--actor cli] [--json]

--from-file is required for both commands. --actor defaults to cli and is part of the plan fingerprint; use the same actor when applying a plan. --json emits one JSON object instead of the human-readable summary. plan is the review step and is mutation-free. apply recomputes the plan from the manifest and current memory state, then requires the supplied --plan-id to match before it writes anything.

Manifest (memzoi/import)

The YAML document has exactly these top-level keys; unknown keys are rejected:

schema: memzoi/import
origin_key: integration:event:123
sources:
- path: imports/source.yml # or url: https://… or ref: issue://123
candidates:
- destination: repo # repo | local | session | discard | needs_review
reason: durable project convention
type: decision # optional when it can be inferred
lane: semantic # optional
title: Explicit candidate title
body: Explicit candidate body
sensitivity: repo-safe # repo-safe | local-only | sensitive | secret |
# raw-transcript | private-personal-data |
# temporary-state | unknown; omitted => unknown
scope:
kind: repo # optional; defaults to repo
id: null # optional
paths: [src/**] # optional; project-relative paths
tags: [workflow] # optional; defaults to []

There must be at least one source and one candidate. Each source needs a non-empty path, url, or ref; a path must be a POSIX project-relative path and cannot be absolute or contain ./.. components, backslashes, or a drive prefix. Candidate destination, reason, title, and body are required and are trimmed before use. Only a repo candidate with sensitivity: repo-safe can create a pending proposal. Omitted sensitivity normalizes to unknown; any other repo sensitivity produces a structured blocked/no-write result. Scope paths have the same project-relative validation, and tags cannot be empty.

The parser is strict at every manifest object (version, sources, candidates, source fields, candidate fields, and scope fields). It rejects malformed YAML, an empty document, unsupported versions, missing required values, empty source locators, invalid paths, an empty candidate list, and candidates whose type cannot be inferred.

Inference is deliberately narrow and deterministic:

  • Without type, lane: episodic or lane: session infers type: episode, and lane: procedural infers type: procedure. Other non-session candidates must provide type.
  • Without lane, type: procedure infers procedural, type: episode infers episodic, and other types infer semantic.
  • A session destination is always normalized to type: episode and lane: session, regardless of a conflicting input value.
  • Missing scope means {kind: repo, id: null, paths: []}. Tags and scope paths are trimmed, sorted, and deduplicated; source locators are trimmed and sorted.

Plan and apply semantics

import plan returns schema memzoi/import-plan, a deterministic plan_id, the normalized sources, a summary, and one normalized result per candidate. With --json, the plan envelope also includes mode: "plan", the effective actor, and the manifest source_file; the plan envelope has no writes field. source_file is project-relative when the manifest resolves under the project root; it is null when the manifest is outside that root or either path cannot be resolved.

The plan fingerprint uses the trimmed actor and normalized plan (including the current duplicate scan), so it is stable for the same actor, manifest, and current memory state. Planning does not create proposal files, canonical records, local/session records, or runtime database writes. A plan may contain private/local candidates; do not blindly commit plan output.

The summary always contains these counters: total, create_proposals, local_writes, session_writes, duplicates, discarded, and needs_review. Each candidate includes index, classification, policy, normalized type, lane, title, body, explicit sensitivity, scope, tags, a trimmed-body BLAKE3 content_hash, duplicates, and action.

Blocked non-repo-safe candidates use classification-only placeholders for title, body, reason, tags, and scope metadata; their original content is represented only by the content_hash. Because manifest sources are document-wide rather than candidate-scoped, the plan omits all source locators when any repo candidate is blocked. It also blocks every other repo candidate in that manifest with guidance to split the manifest before retrying; this prevents a partial repo write from consuming ambiguous provenance. Local and session candidates may still create private runtime records, while blocked repo candidates create no proposal or canonical file.

Action JSON is tagged by action.kind:

{"kind":"create_proposal","proposal_id":"mem_import_example","path":".memzoi/proposals/pending/mem_import_example.md"}
{"kind":"create_runtime","route":"runtime_local"}
{"kind":"create_runtime","route":"runtime_session"}
{"kind":"duplicate","matches":[{"kind":"canonical_record","id":"mem_…","destination":"repo","candidate_index":null}]}
{"kind":"no_write","reason":"stale transient note"}
{"kind":"blocked","reason":"ambiguous privacy boundary"}

repo uses create_proposal and writes only a pending review packet. local and session use create_runtime and write private runtime records on guarded apply. discard is no_write; needs_review is blocked. A duplicate action takes precedence over destination handling and also does not write.

import apply returns the same plan plus mode: "apply", actor, source_file, expected_plan_id, and writes. It recomputes the plan and fails with a stale-plan error when the ID differs; that guard makes a wrong or stale ID a zero-write operation. create_proposal and create_runtime actions produce typed entries in writes:

{"kind":"proposal_file","index":0,"proposal_id":"mem_import_example","path":".memzoi/proposals/pending/mem_import_example.md"}
{"kind":"runtime_record","index":1,"record_id":"local-example","destination":"local"}
{"kind":"runtime_record","index":2,"record_id":"session-example","destination":"session"}

Repo writes create status: proposed OKF proposal files under .memzoi/proposals/pending/; they do not create canonical records under .memzoi/records/. Local/session writes create private active records only in the runtime SQLite plane. Review and explicitly apply the pending repo proposal with the proposal-file workflow when it is appropriate; successful apply updates the derived repo index in the same operation.

Duplicate and no-write behavior

Duplicate detection hashes the trimmed candidate body with BLAKE3 and compares it with canonical records, pending proposal files, active runtime records, and earlier candidates in the same input. Matches are reported as canonical_record, pending_proposal, runtime_record, or earlier_candidate, with their ID and (when applicable) destination or candidate index. Duplicate matches are sorted deterministically; the duplicate action prevents another proposal file.

No files or runtime rows are created when planning, when a candidate is discarded, blocked, or duplicated, when the manifest fails validation, or when apply receives a wrong/stale plan ID. Proposal-file and runtime writes are one guarded operation: a runtime failure rolls back the SQLite transaction and removes proposal files created by that attempt. Import apply never promotes a candidate implicitly and never writes a canonical record directly.

Context JSON

memzoi context --json and MCP build_context_pack return the prompt-ready pack plus metadata. Existing fields such as prompt, records, citations, and token_budget remain available. Recalled record JSON may include proposal_id as review lineage. Citation JSON intentionally uses the original evidence fields instead: provenance (plane), destination, optional source_kind, and optional source_ref.

The serialized provenance values are git and runtime. git identifies ownership by canonical .memzoi/records/*.md files; it does not mean the record bypassed SQLite, because SQLite is a derived runtime index/cache. For recalled records, serialized destination remains repo, local, or session; destination is routing, not provenance. source_kind and source_ref are nullable evidence metadata and remain independent of both one another and proposal_id. Apply/rebuild/export round-trip all three; audit events also identify the approving proposal.

The additive metadata fields are:

  • budget: requested budget, effective budget, approximate used budget, and estimate unit.
  • included: selected records with compact citation, provenance, destination, score, rationale, and estimated size metadata.
  • omitted: capped repo-record metadata for relevant records excluded by budget.
  • warnings: structured notices, currently empty for context ranking.
  • next_queries: targeted follow-up queries, currently empty.

Memory planes and destinations

The policy API accepts these serialized storage-plane values for provenance (and MemoryPlane):

  • git
  • runtime

MemoryDestination::ALL accepts these serialized destination values:

  • repo
  • local
  • session
  • discard
  • needs_review

The policy mapping is:

DestinationPlaneWrite routeReview
repogitfile_backed_proposalproposal_review
localruntimeruntime_localno_review
sessionruntimeruntime_sessionno_review
discardnull (no plane)no_writeno_review
needs_reviewnull (no plane)no_writehuman_decision

This mapping is the normal destination-policy contract. Direct memzoi materialize uses a separate explicit structured-candidate decision and the materialization repository-write route; it does not expand MemoryDestination::policy() or grant other callers direct Git-write authority.

team and cloud are future-only destination labels; they are not accepted serialized values in the current policy. Recalled records can have only the plane-backed destinations repo, local, or session. See Destination classification in the lifecycle policy for destination behavior and lifecycle commands; this reference page intentionally does not duplicate that command matrix.

Handoff JSON

memzoi handoff --json returns handoff metadata plus the full context pack under context. It requires --task or --path; path-only handoff uses the stable effective task Handoff for path <path>.

Top-level fields include:

  • id: handoff pack id.
  • task: effective task.
  • path_prefix: requested path, if supplied.
  • token_budget, include_local, include_session: requested handoff options.
  • proposal_inbox: DB-backed open proposal counts from the proposal inbox, not .memzoi/proposals/pending.
  • context: full context pack JSON, including records, citations, policy, budget, included, omitted, and warnings.
  • created_at: creation timestamp.

Event JSONL export

memzoi events export --jsonl emits runtime event-log rows from SQLite as JSONL. Each non-empty line is one compact standalone JSON object; there is no top-level array, wrapper, or pretty multi-line JSON. An empty event log succeeds with empty stdout.

Event objects include:

  • id
  • event_type
  • actor
  • data_class (repository for exported rows)
  • payload
  • record_id
  • proposal_id
  • created_at

The command exports only events explicitly written with the repository data class. Raw search, context, handoff, and precheck telemetry and events attached to private runtime records remain local even when they have no top-level record_id. Proposal titles and unrestricted rejection or tombstone reasons remain local until repository-write policy has authorized any resulting repository event. Content-free private lifecycle application events remain repository-exportable audit receipts. The JSONL stream is operational runtime state for bulk or append-only consumption. It is not canonical memory, not rebuild input, and does not replace .memzoi/records/*.md or .memzoi/proposals/pending/*.md files. Proposal-file locations in repository events are repository-relative; absolute local worktree paths never cross the export boundary.

Update Command

memzoi update checks GitHub Releases and updates supported Mac/Linux release-binary installs. Automatic apply mode never installs from branches, SHAs, URLs, or shell scripts; unsupported installs may print manual commands that use the official install scripts. Use memzoi update --check to report update state without changing files.

Supported refs:

  • latest: resolve the latest GitHub release.
  • vX.Y.Z: install a stable release tag.
  • X.Y.Z: normalize to vX.Y.Z.

JSON status values:

  • up_to_date
  • update_available
  • updated
  • unsupported
  • invalid_ref
  • download_failed
  • checksum_mismatch
  • rollback_failed

--check --json works from source, Cargo, package-managed, Windows, and CI installs. Apply mode is limited to release-binary installs where memzoi and memzoi-mcp are sibling binaries in a writable, non-package-managed directory.

MCP tools

ToolRequired argumentsOptional arguments
search_memoryqueryscope_kind, scope, type, memory_type, path, path_prefix, limit
inspect_memory_expiryrecord_idnone
build_context_packtaskpath, path_prefix, token_budget
plan_capturestrict schema, sources, extractornone
plan_maintenanceschemaevaluated_at, record_ids
precheck_pathpathscope_kind, scope
precheck_actionactionpath, scope_kind, scope
precheck_commandcommandpath, scope_kind, scope

search_memory, inspect_memory_expiry, and build_context_pack are repository-only at the MCP boundary. include_local and include_session are not accepted MCP arguments. plan_maintenance emits current-schema maintenance evidence from repository records only; MCP exposes no private lifecycle plan, grant, inspection, revoke, or apply capability.

Memory types

Valid --type and memory_type values:

  • fact
  • preference
  • decision
  • procedure
  • episode
  • relationship
  • warning
  • failed_attempt
  • risk
  • instruction_projection

Memory lanes

Valid record lane values:

  • session
  • semantic
  • episodic
  • procedural

Records without lane remain valid and are treated as semantic. lane is separate from type: lane describes memory usage and retention, while type describes the record content.

Proposal file schema values

OKF-compatible proposal files live under .memzoi/proposals/pending/*.md. They are review packets and use:

status: proposed
proposal:
action: create

Valid proposal file actions:

  • create
  • supersede
  • tombstone

supersede proposals require exactly one supersedes target and a reason. tombstone proposals require exactly one proposal.target and a reason. Create packets cannot name a target. Before mutation, apply rejects a target that is missing, inactive, cross-scope, or newer than proposal.proposed_at. update is intentionally unsupported in the file profile.

Valid proposal sensitivity values:

  • repo-safe
  • local-only
  • sensitive
  • secret
  • raw-transcript
  • private-personal-data
  • temporary-state
  • unknown

The current CLI proposal inbox remains DB-local workflow state and uses the operational proposal statuses below. MCP cannot create or change proposal state.

Proposal file review commands:

memzoi proposal-files list
memzoi proposal-files show <proposal-id>
memzoi proposal-files validate
memzoi proposal-files apply <proposal-id>
memzoi proposal-files reject <proposal-id> --reason "..."

list, show, and validate are read-only. They share the same contained inventory as apply, reject, replay, and doctor: symlinked proposal roots are refused without reading outside content, packet/file identities must be globally unique, and a resolved identity cannot return to pending under another filename. list and validate describe the pending inbox; show can also inspect a resolved packet. validate includes target existence, active-state, scope, and freshness checks for repo-safe supersede/tombstone packets, while non-repo-safe packets are invalid with classification-only remediation. Sensitivity is preflighted before the rest of a packet is parsed, so a malformed packet already classified as non-repo-safe is represented by a generic, structurally parseable receipt rather than echoing malformed fields.

apply accepts a status: proposed, sensitivity: repo-safe packet, holds the repo lifecycle lock, writes its canonical changes and derived SQLite rows with rollback for reported failures, then moves the packet to .memzoi/proposals/resolved/applied/. Create writes one active record; supersede preserves the target as superseded and creates one lineage-linked active replacement; tombstone preserves the target evidence with status: tombstoned. reject holds the same lock, creates no canonical record, and moves the packet to .memzoi/proposals/resolved/rejected/ with an explicit reason. A rejected non-repo-safe packet is archived as a create-shaped hash receipt: its original title, body, source, scope, authorship, action target, lineage, proposal ID, and file ID are not copied into Git-visible history or command output. The receipt uses deterministic redacted-identity-… identities, and replay can match either original alias by hashing the lookup without printing it. Repeating an applied outcome checks create/replacement bytes plus lifecycle status, scope, and lineage while treating current canonical target bytes as file-native source of truth; it repairs relational and full-text SQLite drift transactionally. Repeating a rejection is an auditable no-op, and requesting the opposite outcome is refused. Session-end and import proposal writers hold the same lifecycle lock while reserving identities and installing pending files. Reported rollback or cleanup failures are surfaced. The multi-file filesystem and SQLite operation is not crash-atomic across process termination or power loss; memzoi doctor warns about index drift and hidden transaction artifacts without printing unsafe artifact identities.

Git-plane apply blocks every value except repo-safe, including secret, sensitive, local-only, raw-transcript, private-personal-data, temporary-state, and unknown; there is no override flag. Current-format proposal packets must provide sensitivity explicitly. Classify or sanitize blocked proposals before repo apply, or route local/session content to the runtime plane.

With --json, sensitivity-blocked apply, supersede, and proposal-files apply commands exit nonzero after emitting a content-free error object on stdout. The envelope uses ok: false and an error object containing code: repo_sensitivity_required, the operation, classification, message, and next step; proposal bodies and other rejected fields are not included.

Local runtime memory

Local memory commands:

memzoi local add --type preference --title "..." --body "..."
memzoi local list
memzoi local search <query>

Local records are stored in the repository-shared runtime database under ${MEMZOI_HOME:-~/.memzoi}/projects/<repository-key>/shared.db. They are visible from every linked worktree and are marked as destination: local, visibility: private, and source_kind: memzoi-local in JSON output.

Local records are not written to .memzoi/records/**, are not returned by global memzoi search, and are not exported into repo-shared agent files. memzoi context is repo-only by default and includes local records only with --include-local. Use later proposal workflows to promote local memory into repo-shared memory.

Session checkpoints

Checkpoint commands:

memzoi checkpoint add --task "..." --note "..."
memzoi checkpoint add --task "..." --from-file notes.md
memzoi checkpoint continue <checkpoint-id>
memzoi checkpoint close <checkpoint-id>
memzoi checkpoint add --task "..." --note "..." --successor-of <checkpoint-id>
memzoi checkpoint list

Checkpoints are stored in the repository-shared runtime database under ${MEMZOI_HOME:-~/.memzoi}/projects/<repository-key>/shared.db. They are visible from every linked worktree and are marked as destination: session, lane: session, type: episode, visibility: private, and source_kind: memzoi-checkpoint in JSON output.

Checkpoints store only explicit --note or --from-file content. They are not written to .memzoi/records/**, are not returned by global memzoi search, and are not exported into repo-shared agent files. memzoi context is repo-only by default and includes checkpoints only with --include-session. Use later session-end proposal workflows to promote durable findings into repo memory.

The session retention boundary is the earliest of closure, 24 hours after the latest continuation or start, seven days after the original start, and an explicit expiry. Continuation is allowed only while open and current; closure is terminal and idempotent. --successor-of creates a new generation from a closed or expired checkpoint and records its predecessor lineage.

For --json, lifecycle commands require caller-controlled --operation-id and the current --expected-version (except a new checkpoint without a predecessor, which has no expected version). An exact retry returns the prior outcome before checking the now-stale version. Reusing an operation ID with changed parameters fails with origin_reuse_mismatch and performs no writes.

Session-end promotion

Session-end promotion reads only explicit structured YAML, either from a file or from an existing checkpoint body:

memzoi session-end --from-file notes.yml
memzoi session-end --from-checkpoint <checkpoint-id> \
--operation-id <operation-id> --expected-version <record-version>

The input must include a task and a candidates list:

task: "Implement auth middleware"
candidates:
- destination: repo
type: decision
lane: semantic
title: Protected routes validate sessions server-side
body: Protected routes must validate sessions server-side.
sensitivity: repo-safe
reason: Learned while implementing middleware.
scope:
kind: repo
paths:
- src/auth/**
tags:
- auth
- security

Memzoi validates the whole batch and prepares repo proposal files before writing. repo candidates must be repo-safe and become pending .memzoi/proposals/pending/*.md proposal files only; omitted sensitivity normalizes to unknown. If any repo candidate is not repo-safe, the command returns structured blocked results, redacts that candidate's title from output, and performs no writes for the entire batch. Otherwise, local candidates create private runtime records and session candidates create runtime checkpoint records. Runtime row writes are transactional, and created proposal files are cleaned up if a later promotion step fails. discard and needs_review candidates create no writes.

session-end does not inspect transcripts, chat logs, shell history, hidden agent state, or context packs. Free-text notes and checkpoints are rejected until a future extraction workflow exists.

Scope kinds

Valid --scope-kind, scope_kind, and scope values:

  • personal
  • repo
  • project
  • team
  • org
  • agent
  • imported_untrusted

Visibility values

Valid visibility values:

  • public
  • private
  • repo
  • team
  • org

Exports skip private records.

Status values

Operational proposal inbox statuses:

  • pending: proposal exists but has not been approved.
  • validated: validation passed, but approval is still required. This state remains supported even when most flows do not create it.
  • approved: proposal is approved for durable write, but canonical .memzoi/records/*.md has not been written.
  • applied: proposal produced an active canonical record and no longer blocks rebuilds.
  • rejected: proposal was intentionally closed without applying.
  • open: synthetic filter meaning pending, validated, or approved.

DB proposal transitions are monotonic: repeated approval or rejection of the same current state is idempotent, while terminal applied and rejected proposals cannot be reopened.

Record statuses:

  • active
  • superseded
  • expired
  • tombstoned
  • redacted

Auto-approval means approved, not applied.

Approval policy

Effective proposal approval mode is resolved in this order:

  1. Built-in default: auto.
  2. User-global config: ${MEMZOI_HOME:-~/.memzoi}/config.toml.
  3. Repo config: .memzoi/config.toml.
  4. CLI per-call override.

Config shape:

[workflow]
proposal_approval = "manual" # or "auto"

CLI overrides:

  • memzoi propose --manual creates a pending proposal.
  • memzoi propose --auto-approve forces auto-approval for one proposal.
  • memzoi propose --apply --sensitivity repo-safe creates, approves, and applies through the CLI. It is incompatible with --manual.
  • Omitted sensitivity is serialized as unknown; validation and apply both refuse canonical promotion until it is explicitly repo-safe.

MCP boundary:

  • MCP exposes no proposal creation or approval-policy override, and never creates proposal state or writes canonical records.

Export formats

Valid memzoi export <format> values:

  • okf
  • agents-md
  • claude-md

v0 limitations

  • Source installs require a Rust/Cargo-capable environment; release binaries do not.
  • Search is text/FTS-first, not vector or semantic recall.
  • Memory is repo-local; global, personal, team, and org sync are future work.
  • memzoi rebuild restores canonical records from .memzoi/records/ into the current worktree's disposable index.db. Repository-wide local/session memory and proposal state remain authoritative in shared.db, so open proposals do not block rebuild. An unreadable shared.db fails closed before the worktree index is replaced.
  • MCP is intentionally minimal, repository-only, and read-only. It cannot create proposal state or apply canonical records.
  • Homebrew and package-manager installers are not available yet.