CodeHerderSearch⌘KRequest access →

← All docs

Workspace memory

How workspace memory stores durable learnings that survive session resets — entry anatomy, scopes, kinds, the review gate, what an agent actually recalls and how a confirmed change reaches agents already at work, the store's size limit, reading and writing entries from the web app and CLI, and backing up or migrating your workspace memory.

Because every agent session starts with a clean context — no shared transcript, no carry-over from prior sessions — knowledge that matters across tasks needs somewhere permanent to live. Workspace memory is that place: a shared store of entries that persists across session resets, task boundaries, and agent restarts.

Every confirmed entry is visible to all members of the workspace. When a new agent session starts, the relevant slice of memory is pre-loaded into the agent’s brief, so it walks in knowing the team’s accumulated conventions, decisions, and known pitfalls — see What your agents actually recall below for exactly what that means, and Changes reach agents already at work for what happens when memory changes mid-run.

What an entry looks like

Each memory entry has five parts:

  • Title — a short, human-readable name for the entry (for example, “Deploy needs AWS_PROFILE”).
  • Slug — a unique key for the entry within the workspace (lowercase letters, numbers, and hyphens). Writing an entry with the same slug as an existing one updates it in place.
  • Scope — who the entry is shared with (see Scopes below).
  • Kind — what type of knowledge the entry captures (see Kinds below).
  • Body — the text of the entry itself, written in plain prose or markdown.

Scopes

workspace_shared (the default) makes an entry visible to every member of the workspace and available in agent recall, and is inherited by nested/child workspaces. Because it is team-wide, writes from regular members go through a review gate: the entry lands as pending and does not appear in agent recall until an admin or workspace owner confirms it. Admins and owners write directly to confirmed status. --agent is not allowed with this scope.

template_persona attaches an entry to a single agent template, for per-agent tuning — it is node-local and is not inherited by nested/child workspaces the way workspace_shared is. Pass --scope template_persona together with --agent <agent> (its display name or member ID) when writing; --agent is required for this scope. It skips the review gate: the agent it belongs to, or an admin or workspace owner, writes it directly to confirmed status. No other member can write another agent’s persona memory.

Kinds

Four kinds describe what a memory entry captures:

Kind Use for
fact A factual statement about the project — architecture decisions, known constraints, recurring gotchas. This is the default.
feedback Guidance on how agents should approach their work.
project Ongoing work context — active goals, current priorities, in-flight constraints.
reference Pointers to external resources — URLs, dashboards, ticket numbers.

Pass --kind <kind> when writing. Omitting it files the entry as fact.

The review gate

Any workspace member can propose a workspace_shared entry. When a regular (non-admin) member writes one, it lands as pending — stored but excluded from recall until reviewed. An admin or workspace owner then confirms the entry (making it live) or archives it (keeping it off the recall index permanently).

This gate keeps shared knowledge trustworthy. An unreviewed agent-proposed learning does not influence other agents until a human has approved it.

This gate applies to workspace_shared entries only. A template_persona entry skips it entirely — see Scopes above.

Confirm a pending entry (admin/owner only):

ch memory confirm <slug|id>

Archive an entry (admin/owner only):

ch memory archive <slug|id>

Archived entries are retained for audit but removed from recall. The Memory page in the web app shows admins a pending queue so they can review proposed entries without opening the CLI — and the Memory link in the sidebar itself carries a badge with that same count, so you know a review is waiting before you even click in.

What your agents actually recall

An agent session only ever sees confirmed entries — a pending or archived entry never reaches it, no matter how relevant.

Confirmed entries reach the agent in two forms. A short index — one line per entry, most recently updated first, up to a fixed budget — is pre-loaded straight into the agent’s brief before it starts. The full text of every confirmed entry the agent can see is also written into the session’s own workspace as a knowledge folder at .codeherder/knowledge/ (with an index.md at its root), so the agent can read any entry in full the moment the one-line summary in its brief isn’t enough.

A session in a nested workspace gets its own workspace’s entries plus the workspace_shared entries it inherits from parent groups — see Scopes above.

Keep an entry short and specific — one fact per entry — rather than pasting a long document into one. See Size limits below: an oversized body is rejected when you try to save it, not trimmed down for you, so write the concise version up front.

Agents treat every entry as reference material to check, not as an instruction. Workspace memory is a team wiki the agents read, never a way to configure their tools or issue them orders.

Changes reach agents already at work

Confirming a pending entry, or updating a confirmed one, refreshes the knowledge folder for every session currently running in that workspace and in the workspaces nested beneath it, and lets those agents know the workspace’s knowledge changed.

You don’t need to restart anything, and there’s nothing to configure — devices keep their own CodeHerder software current automatically, which is what makes the live refresh work (see Updating the CLI).

That’s why the pending queue is worth tending promptly: confirming an entry lands with agents mid-run, not just on the next task they pick up.

When an agent proposes an entry

An agent that learns something durable during a run writes it up, and CodeHerder files it through exactly the same governed path as ch memory write — so the review gate above applies unchanged: a workspace_shared entry an agent proposes lands pending and does not influence any other agent until an admin or workspace owner confirms it. This is where most of the entries in your pending queue come from.

An agent doesn’t only propose brand-new entries — it can also edit one it already has read access to, right in its own copy. CodeHerder picks up that in-place edit the same way and files it through the same governed path, so a correction to an existing entry lands under the same review gate a new one would.

An entry an agent writes about itself (template_persona) skips the gate, the same as when a person writes it — see Scopes above.

Filing doesn’t wait for the run to end. CodeHerder picks up a new or edited entry within seconds of the agent writing it, then makes a final pass when the session finishes to catch anything left over — so a proposal can already be sitting in your pending queue while the agent is still working. ch memory sync-drafts files anything still waiting, if you want to trigger it by hand — it reads the session’s .codeherder/knowledge-draft/ folder by default. An entry that’s byte-identical to the one already stored is skipped, and a draft never overwrites a confirmed workspace_shared entry.

Size limits

Three limits apply when you write an entry:

  • Body — up to 8 KB. Go over, and the write is rejected with an error rather than trimmed — split a long note into more than one entry instead.
  • Slug — up to 128 characters.
  • Title — up to 200 characters.

How much a workspace holds

A workspace holds up to 100 confirmed entries. Past that, a confirmed write that would push it over the limit automatically archives the least-recently-updated entries to bring it back under. Pending entries don’t count toward the limit.

Writing an entry again under the same slug refreshes it, moving it back to the front of the recall order and away from the eviction edge — reinforcing an entry is how you keep a still-true fact from aging out.

If you know an entry is obsolete, archive it yourself rather than letting the limit choose for you: recall order is driven by how recently an entry changed, not by how important it is.

Reading and writing memory

In the web app

Open Work → Memory in the sidebar. Browse confirmed entries with the Scope and Kind filters, or search by title or slug. An entry inherited from a parent group carries an Inherited chip and is read-only here — see Resource inheritance for where to edit it instead. If you are an admin or owner, a separate Pending review section lists workspace_shared writes from non-admins awaiting your confirm or archive.

Click New entry — in the page header, or in the empty-list message if the workspace has no memory yet — to open the write form: Title, Slug, Scope, Kind, and Body. Saving follows the same rules as the CLI: a workspace_shared write from a non-admin lands pending. The form’s Scope dropdown lists template_persona too, but there’s nowhere in it to pick which agent the entry belongs to, so leave Scope on workspace_shared here — write a persona entry from the CLI with --agent <agent> instead (see Scopes above).

Open an entry to read its full body, then use Edit to change it. Admins and owners also get an Archive button for retiring it. Neither button appears on an inherited entry. Editing a confirmed workspace_shared entry as a non-admin sends it back through the review gate — your change replaces the confirmed body but sits as pending, and drops out of recall until an admin or owner confirms it again.

From the CLI

List all confirmed entries in the workspace:

ch memory list

Add --limit N to cap how many rows come back. It only narrows the list — the recall index itself holds at most 100 confirmed entries per workspace (see How much a workspace holds above), and --limit can’t raise you past that.

Read a single entry in full (including its body). <slug|id> accepts the entry’s slug or its full UUID:

ch memory show <slug|id>

Write a new entry (or update an existing one by reusing its slug):

ch memory write --slug <slug> --title "<title>" --from-file note.md
ch memory write --slug <slug> --title "<title>" --from-file -
ch memory write --slug <slug> --title "<title>" --body "Short inline text."

Optional flags for ch memory write:

Flag Default Purpose
--scope workspace_shared Scope of the entry: workspace_shared (team-wide, review gate applies) or template_persona (one agent template).
--kind fact Kind: fact, feedback, project, or reference.
--agent The agent’s display name or member ID. Required with --scope template_persona; not allowed with workspace_shared.

If your workspace_shared write lands pending, CodeHerder prints a note with the memory ID and the ch memory confirm command an admin can run to approve it.

A file you pass to --from-file can carry the entry’s title, slug, kind, scope, and agent right in its own front matter — the same front matter ch memory export writes (see Backing up and migrating memory below), so a note you exported can be edited and written straight back with no flags at all. A flag you do pass always wins over what’s in the file:

ch memory export ./backup
ch memory write --from-file ./backup/knowledge/workspace_shared/fact/deploy-profile.md

An agent’s own proposed entries, and any in-place edits to entries it already has, file automatically while it works, but you can trigger the same filing by hand:

ch memory sync-drafts

Add --json to any ch memory subcommand to get the raw JSON response instead of the formatted output.

Backing up and migrating memory

The CLI can export your entire workspace memory to a folder on disk and import it back — useful for backup, disaster recovery, or moving entries to another workspace.

Exporting

ch memory export ./memory-backup

The folder is created automatically if it does not exist. The export includes:

  • Confirmed entries — always included.
  • Pending entries — included if you are an admin or workspace owner; if you are not, they are skipped and the CLI prints a note.
  • Archived entries — not exported. Archived entries are retained by CodeHerder for audit but are not accessible via the export path.

Importing

ch memory import ./memory-backup

Import reads the backup folder and writes each entry back through the same governed path as a regular ch memory write. What that means in practice:

  • Workspace target — entries are written into your active workspace, so make sure that’s set to the destination before running the import — see Selecting your active workspace in the CLI.
  • Review gate — the same rules apply as for any write. If you are not an admin or owner, workspace_shared entries land as pending and require an admin to confirm them before they appear in agent recall. Admins and owners write directly to confirmed.
  • Slug matching — if an entry with the same slug already exists in the target workspace, it is updated in place rather than creating a duplicate.
  • What is preserved — scope, kind, slug, title, body, and agent association (for template_persona entries).
  • What the server re-assigns — entry ID, status, source member, workspace ID, and timestamps. These are always server-assigned on import and cannot be restored from the export file.
CodeHerder

Round up your herd.

Bring every human and every agent onto one table. Watch what's happening, see what's stuck, and know what it's costing you, live.

Try "pricing", "connect a device", or "who reviews the code"

↑↓ move · ↵ open · esc close