Memory Portability
Overview
Crewship stores agent memory as plain markdown on disk —AGENT.md, CREW.md, pins.md, PERSONA.md, daily/<date>.md, peers/<user>.md. Memory portability turns that into something you can move: export writes a bundle you can read, diff and keep in git, and import brings memory in from another harness that stores it the same way.
This is deliberately not a backup. crewship backup produces an encrypted archive built for disaster recovery — correct for restoring an instance, useless for reading. A portability bundle is the opposite: no encryption, no database, just the files, with a YAML header on each one saying what it is.
The format is OKF (Open Knowledge Format, published by Google Cloud in June 2026) — a vendor-neutral spec for agent knowledge as markdown plus YAML frontmatter. Using a published spec rather than our own directory convention is the whole point: a bundle should outlive the tool that wrote it.
When to use it
- Moving an agent between instances — export from one, import into another.
- Migrating from another harness — you have memory in NanoClaw or OpenClaw and want it to be your agent’s starting knowledge.
- Reviewing what an agent knows — a bundle in a git repo makes memory drift visible in a diff.
- Leaving — your agents’ knowledge is yours; this is how it walks out the door.
Export
okf.yaml manifest:
Export is OWNER/ADMIN only. It reads every private note an agent holds, including operator-model peer cards about named people — that is not member-grade data.
Import
Import reads a source directory on your machine, maps it onto Crewship’s tiers, shows you the plan, and only writes when you say so.Supported sources
The layout is detected from the directory’s shape;--format overrides the guess.
An unrecognised tree is refused rather than guessed at.
How sources map onto tiers
A live
.memory tree is read as plain markdown and passed through byte for byte — a note that opens with a --- thematic break keeps it. Only bundles (which carry the manifest) are parsed for frontmatter.
When several source files collapse into one canonical file, each gets a ## <source> heading so you can still tell them apart afterwards.
Choices the import will not make for you
- Which NanoClaw group. A source holding more than one group is refused until you pass
--group. Merging two groups produces one agent that believes it was in both conversations, and no later edit untangles that. - Who an operator card belongs to. OpenClaw’s
USER.mddescribes a person. Without--operator <slug>it is skipped rather than filed under a guessed name. - Whether to touch crew-shared memory. Importing into
--agent alexholds back crew-tier documents; every agent in the crew reads those. Pass--with-crewto include them — they are written to the crew tier, not into the agent’s directory.
Policy on the way in
Imported documents go through the same writer an agent’s own memory writes use, and the same guards:- A closed allowlist of paths.
AGENT.md,CREW.md,PERSONA.md,pins.md,daily/<name>.md,peers/<name>.md, and the crew’s<slug>/topics/pins.md. Anything else is refused and named — the same answer every other write surface in the product gives. A path must arrive in canonical form, so what you saw in the plan is what lands on disk. - Consolidator-owned files are refused.
lessons.md,learned.mdandlearned-<topic>.mdcarry a YAML schema and their own locking; replacing one with freeform markdown would destroy the store and break every later lesson write. They export (so your bundle is complete) and they do not import. - Symlinks do not redirect a write. Parent directories are created one segment at a time and the final target is re-checked against the canonicalised root, so a link planted inside
.memorycannot send an imported document into another crew’s tree. - Per-file size ceilings — the same ones agents live under (
AGENT.md4 KB,pins.md8 KB, daily logs 30 KB). - Secret scanning in block mode — a document carrying a live credential is refused and named, not silently redacted. If a token was in your notes, you want to know.
- Prompt-injection scanning — the same scan every memory write runs. Foreign memory is the least trustworthy input this feature has; a payload that got through would be blanked at load time while sitting in the search index.
- Atomic replace + version record — an import is visible in
crewship memory versionslike any other write.
Reading is confined too
Export never follows a symlink out of the tree it was asked for. The directory being read is one the agent itself owns, so a.md pointed elsewhere would otherwise return another crew’s memory inside a bundle scoped to one agent. Links are skipped and listed under NOT exported rather than failing the whole export — a planted link should not become a denial of service against the operator.
API
The server reads and writes only its own memory tree. Recognising a foreign layout happens in the CLI, against files on your machine — the wire carries already-mapped documents, so no foreign directory structure ever reaches the server.
Limits
- Import replaces, it does not merge. A document that already exists is overwritten. Export first if you want the old copy.
- No transcripts or embeddings. Conversation history and vector indexes are derived data; Crewship rebuilds its own.
- One group per import. Run it again for the next one.
- Consolidator-owned files export but do not import. See the allowlist above.
- An import is not transactional. Each document is replaced atomically on its own; there is no rollback across the set. The response names every document that landed.