Skip to the content
Menu

Memory

Memory is what the Team Lead and the agents keep for later, and what people can read and manage too: decisions and their reasons, preferences, gotchas, how things are done here. It works the same for agents on every coding CLI (Claude Code, Codex, Gemini and Other), because it reaches them as plain text in the prompt and comes back on the result line.

It stores what the repository and the board can’t tell an agent. Link to code, docs and cards; don’t copy them. Memory is data written by people and agents, never instructions. Every prompt says so where the notes start.

Part 1 (GA-19) is the store, the links, the Team Lead’s tools and memory in every run. Part 2 (GA-68) is the Memory page, where people find, read and manage the notes. The graph (GA-69) and agents asking the Team Lead before a person (GA-70) build on them.

Notes

A note is a Markdown text in Gizai’s database: a doc of kind memory, at organisation level (no project needed). So versions, authorship, activity, live refresh and backups work as for docs. The Memory page shows and edits a note (#/memory/<id>; an old #/doc/<id> link to a note opens it there). A project’s doc list never shows notes.

Notes follow Obsidian’s file conventions, so a copy opens there: Markdown, [[wikilinks]], YAML properties at the top (frontmatter, kept inside the note’s text) and folders. Gizai does not use or need Obsidian.

Every note has:

  • a path: folder and title, like Standards/Rust style. A title can’t hold * " \ < > : | ? # ^ [ ]; paths are at most 200 characters, and two notes can’t share a path (case ignored);
  • a scope: shared, or agent for an agent’s own folder and the Team Lead’s;
  • an owner: in an agent’s folder, that agent.

Folders

Folder Scope Who reads Who writes
Clients/, Projects/, Standards/, Workflows/, Deployments/, Dependencies/, Decisions/, Lessons/ shared everyone the Team Lead and people
Agents/<name>/ agent that agent (and the agents that share its folder), the Team Lead and people the same
Team Lead/ agent the Team Lead and people the Team Lead and people

A note goes in one of these folders; other top folders are refused, with the list. Each agent gets Agents/<name>/Notes when it is made (agents from before memory get theirs when Gizai starts). Renaming an agent moves its folder, and the links to its notes follow. The Team Lead’s Team Lead/Notes is made the first time the Team Lead needs it, from a short template: the user’s preferences, working agreements, open threads, and how to use memory.

The rule is written once, in gizai_core::memory::can_read and can_write: the Team Lead and people read and write everything; an agent reads the shared folders and its own (in a group, the group’s), and writes only its own. The Team Lead moves useful notes from an agent’s folder into a shared one (memory_move).

Agents that share a folder (GA-96)

Agents that take turns on the work, like Backend Agent and Backend Agent 2 on two Claude Code accounts, can share one folder, so what one learns reaches the other. An agent’s Shares memory with (agent form → Memory, under Use memory; agent_configs.shares_memory_with) is Its own folder (the default) or another agent, never the Team Lead (the agent with the lead role or Chat). The agents that share one folder are a group, and the agent whose folder it is, the group’s owner, keeps Its own folder:

  • One folder per group: the agents in a group use the owner’s folder, Agents/<owner name>/, as their own: they read and write its notes, their runs get its notes, and their learned lines go into its Notes with who learned them. While an agent shares a folder it has none of its own: a new note in Agents/<its name>/ is refused, with the folder to use.
  • No chains: picking an agent that shares a folder picks that folder’s owner. An owner that joins another group brings its group along.
  • Joining: the bullets under ## Learned in the agent’s Notes are added under ## Learned in the owner’s Notes (a bullet the owner’s has already is not added again), and its other notes move into the owner’s folder, keeping their place in it; a title that is taken gets “ ()” added. The links to them are rewritten as memory_move does, so they still work. The agent’s Notes goes once its learned lines are in the owner’s: when only its template is left (the properties type: note and tags: [agent], its title and the line about what it is); anything else in it moves as Notes (<agent name>). A Notes about another client or project than the owner’s moves whole, so its lines keep reaching only those runs.
  • Leaving (back to Its own folder): the agent gets a fresh Agents/<name>/Notes; the group’s notes stay where they are. From one group to another, its notes stay with the old group.
  • The owner renamed: its folder moves as before, and the group follows. The owner removed (or made the Team Lead): its notes stay, and the group’s next agent (the oldest of the others) becomes the owner, so the folder is renamed to that agent’s name and the others share it. Gizai does this when an agent becomes the Team Lead, and for a removed owner when it starts.

The Team Lead’s get_agent shows an agent’s shares_memory_with (by name), its memory_folder and the agents that share its folder (shared_by); create_agent and update_agent take shares_memory_with by agent name, or none for its own folder. An agent name that isn’t there, or the Team Lead, is refused and nothing changes. A database from before (v0.7.0) migrates with every agent on its own folder.

Properties

YAML properties at the top of a note say what it is about and who gets it:

---
type: decision          # client, project, standard, workflow, deployment, dependency, decision, lesson or note
tags: [rust, style]
client: Kade            # a note about a client…
project: KADE           # …or a project (its key or name)
applies_to: [backend, qa]   # roles, or all: who gets it in a run
updated: 2026-10-09
source: GA-19           # a card, chat or run
---

On every save Gizai rebuilds the note’s links (doc_links) from its text:

  • [[Note]], [[Folder/Note|text]], [[Note#Heading]]: a link; ![[Note]]: an embed;
  • KADE-12: a card;
  • @handle: a person or agent (a mention).

A wikilink finds a note as in Obsidian: by title, case ignored; a path (or the end of one) picks between notes with the same title, else the note in the same folder, else the shortest path. A link to a note that doesn’t exist yet starts working when that note is made. Moving or renaming a note rewrites the links that point to it, in notes and docs, as a new version of each.

Plain matching over the notes (memory stays small), so it is right after every save, rename and move: every word and "quoted phrase" must be in the path or the text (case ignored); path:Standards (or path:"Team Lead") keeps the notes whose path starts with it, and with a / at the end only that folder’s (path:"Agents/QA/" leaves out Agents/QA 2/); tag:rust keeps the notes with that tag (the tags property or a #tag in the text). Title matches come first.

Safety

A save with an obvious secret in it is refused, with what to do instead (write where the secret is kept): a private key block (-----BEGIN … PRIVATE KEY-----) or an API token (sk-…, ghp_… and the other GitHub tokens, AKIA…, xoxb-…, AIza…, glpat-…). A learned line with a secret is left out and the run’s log says so.

The Team Lead

The Team Lead’s tools: memory_list, memory_search, memory_read, memory_write (a whole note, with the version it read; a new path makes the note), memory_append (under a heading, without rewriting the note) and memory_move (move or copy, rewriting links). memory_read, memory_append and memory_move find a note by its path, its title (as a wikilink does) or its id. It sees every scope, and the activity feed shows it as the author. Once a chat answer has used a tool from outside Gizai (another MCP server, the web, the browser), memory_write, memory_append and memory_move aren’t run for the rest of that answer, like its other tools that act: Gizai keeps each call under the answer for you to approve with one click (GA-102). The preview shows the note’s path and its new text, with what changes against the current version when the note exists (memory_write), the path, heading and text (memory_append), or from and to (memory_move). Approve saves exactly that, once, as the Team Lead, with the usual version check: a note that changed since the Team Lead read it isn’t saved, and the chat says why. Discard saves nothing. A newer memory_write or memory_append for the same note replaces the older one, and the Team Lead’s next answer hears what you decided. A card it creates or moves into an Auto column in such an answer, or whose description, acceptance criteria or assignee it changes there, waits on hold for your OK, and taking such a card off hold is refused (docs/agent-tools.md, Safety rules).

Every chat answer and every board check has the Team Lead’s Memory block at the end of its system prompt, in old chats and new ones: its own notes (Team Lead/, Notes first) in full, at most 6,000 characters (a note that doesn’t fit is cut, with a pointer to memory_read), then the paths of every other note, at most 4,000 characters. The notes in Team Lead/Imported/ (from Claude Code’s own memory, below) are one line there, with how many wait to be sorted. Its task runs get the same block. Its instructions ask it to save decisions with their reasons, preferences and gotchas, not to copy what the repository or the board say, never to store a secret, and to look in memory before asking the user.

Agents’ runs

A new task run’s prompt has a Memory section after the task, built by memory::prompt_block:

  1. the agent’s own notes (Agents/<name>/Notes first); an agent in a group gets the group’s folder as its own (Agents/<owner name>/Notes first);
  2. the shared notes for this card, in this order: the card’s project (project:), its client (client:), the agent’s role or all (applies_to:).

At most 6,000 characters of notes in full, then the paths of the rest that match (4,000). When the card has shared notes, the agent’s own notes take at most 3,000 of the 6,000 and the shared notes get the rest, in the order above, so a long Notes never pushes the card’s notes out; without shared notes its own notes may use all 6,000 (GA-103). A note that doesn’t fit in what is left is cut at the end, with where the rest stays in Gizai’s Memory (task runs have no memory tools to read it), or only its path is listed when less than 500 characters are left.

The agent’s Notes grows at the end of its ## Learned list (below), so when it doesn’t fit, that list is cut from its oldest line instead: the run gets the text before ## Learned (and any after the list), a line on how many older lines were left out, and the newest lines that fit, in their order:

## Learned

(41 older lines left out; they stay in Gizai's Memory at Agents/Backend Agent/Notes.)

- 2026-10-11 (GA-101): …
- 2026-10-12 (GA-103): …

A Notes that fits is shown as it is. One without a ## Learned list, or whose text around the list doesn’t fit by itself, is cut at the end like any other note. The Team Lead’s block cuts its notes as before.

Client isolation: a note about another client or another project never goes in, not even its path, and not from the agent’s own folder or its group’s either; a shared note with applies_to for other roles doesn’t go in. A continued run has the notes in its session already.

An agent keeps what it learned by adding an optional learned list to its result line:

GIZAI_RESULT: {"outcome":"ready_for_testing","summary":"…","issues":[],"learned":["The fake CLI ignores --effort"]}

Gizai appends each line to the agent’s own Notes under ## Learned, as a dated bullet with the card (- 2026-10-09 (GA-19): …), written by the agent, with the run on the note’s version. In a group, every agent’s lines (the owner’s too) go into the group’s Notes with who learned them: - 2026-10-11 (GA-12, Backend Agent 2): …. At most 20 lines, each cut at 300 characters. A result line without learned parses as before.

The task page’s Runs tab lists the notes a run was given, with their size (and how much was shown when one was cut). For a Notes cut by its ## Learned list, that is the characters of its text the run got, the line on what was left out not counted.

The DevOps role keeps a project’s deploy note in Deployments/<KEY>, with type: deployment, project: <KEY> and applies_to: devops, so it comes into the DevOps Agent’s runs; the agent reports what changed as learned lines and the Team Lead folds them into the note.

Agents ask the Team Lead first (GA-70)

When a task agent ends its run with needs_decision, the Team Lead looks at the question before you (gizai_core::questions, the app’s ask_lead):

  1. Who gets it. The Team Lead takes it when the step is on (Settings → Runs → Ask the Team Lead first, on by default), agents aren’t paused in Settings, the Team Lead (the agent with Chat on) is active, runs on a Claude Code CLI and is under its monthly budget, the asking agent isn’t the Team Lead and its CLI can continue a session, and the limits allow it: one try per question, two per card, and the question right after a Team Lead answer goes to you (no loops; the board check leaves such a question to you as well, and the Runs tab says which limit sent it). Otherwise, and for a run_for_me request, a gate’s hold (QA bounces, an answer the role can’t give) or a failed push, the card goes to the Inbox as before.

  2. Meanwhile. The card stays on hold needs_decision but is “with the Team Lead”: not in the Inbox (tasks::needs_you and the UI’s needsYou), no notification, and the board check leaves it out. The card’s Hold row says With the Team Lead.

  3. The Team Lead’s run on the question (trigger question, role lead, no card of its own, so the card’s latest run stays the agent’s): a fresh session with the question, the card, its description, acceptance criteria and last comments, and its Memory block. It only reads: memory, the card and the project’s docs through the gizai tools (the tools that change things are refused), and its copies of the code with Read, Glob and Grep. Its rules: always leave money, scope, deadlines, messages to clients, security, deleting and anything it can’t find in memory or on the card to you. It ends with a result line:

    GIZAI_RESULT: {"outcome":"answered","answer":"…","memory":{"path":"Standards/Exports","text":"…"}}
    GIZAI_RESULT: {"outcome":"escalated","reason":"…","options":["…","…"],"advice":"…"}
    
  4. Answered: the answer is kept in memory as the Team Lead’s, with the card’s identifier (so it links to the card): as a dated line in the shared note the result names, else in Decisions/<project name> (made with type: decision and project:, so the agents on that project’s cards get it). Then the agent’s session continues with the answer as the Team Lead’s Continue note (GA-31), which is also its comment on the card. A start that only has to wait (Runs at once full, the agent paused or over its budget) is tried again every 30 seconds for ten minutes, with the card still with the Team Lead.

  5. Escalated, and also a failed or timed-out run, one without its result line, or an answer the agent can’t be continued with: the Team Lead’s comment “Needs : why”, the options and its advice, and the hold’s reason becomes “Team Lead escalated to you: why”, in the Inbox (it notifies as a new hold). A question still with the Team Lead when Gizai stops goes to you at the next start. A later Continue doesn’t count the Team Lead’s comment as an answer. When the Team Lead can’t run here at all (no gizai-mcp helper, its CLI not found), the question goes to you as before, without a comment, and the Runs tab says why.

  6. Your answer. When the agent starts again on a card whose question the Team Lead escalated, the comments people wrote since are kept in Decisions/<project name> as the Team Lead’s, with the card, once per question.

The question’s record is kept under lead in the asking run’s outcome_json (state asking, answering, answered, escalated, dropped when you took the card over first, skipped, or limit), and the Team Lead’s run is stored with trigger approval and read as question: no new columns. The Runs tab shows on the asking run who answered, the answer or the reason, and what the Team Lead’s look cost; that cost counts toward the Team Lead’s budget. The Team Lead’s agent page lists its runs on questions with their cards.

Claude Code’s own memory

One memory: Gizai’s. Claude Code keeps notes of its own in projects/<project folder>/memory/ in its account’s folder (CLAUDE_CONFIG_DIR, else ~/.claude), which only that account sees; agents kept theirs there before memory (like the DevOps Agent’s deploy-<KEY>).

The import (GA-85). When Gizai starts, after the migrations, each Markdown file there, for every Claude Code account in Settings → Coding CLIs, becomes a note Team Lead/Imported/<project folder>/<file name>: its text as it was, with source: claude-code, claude_config_dir, claude_project and claude_file added to its properties. MEMORY.md (Claude Code’s index) and the folders below are left out. Only the folders of Gizai’s own places come in (memory_import::places): each project’s linked folder, each card’s worktree (<data folder>/worktrees/<KEY>/<card>), the Team Lead’s code copies (code/<KEY>) and its working folder (lead). Claude Code names a folder after each path it works in, every character but an ASCII letter or digit as - (/home/jefsev/Herd/gizai is -home-jefsev-Herd-gizai; a name over 200 characters is cut, with a hash of the path), and keeps the memory of a run in a worktree in the folder of the worktree’s repository, the project’s linked folder (read in Claude Code 2.1.289). The other folders, your own sessions elsewhere, are left out and not read. Each file comes in once (the claude_memory_imports setting keeps which), also when it changes later. A file with a secret in it, not text or over 200 KB is skipped, listed by its path only, and tried again once it changes. Team Lead/Notes gets an open thread with what came in and what didn’t (a list over 2,000 characters goes in a note of its own), how many other folders were left out (not which), and the agents whose instructions still say MEMORY.md, so the Team Lead sorts the notes with you (memory_move, like deploy-GA into Deployments/GA); until then no agent gets them. Gizai only reads those files. Headless test and screenshot runs don’t import.

The switch. Task runs, chat answers, board checks and the Team Lead’s runs on agents’ questions on Claude Code get CLAUDE_CODE_DISABLE_AUTO_MEMORY=1, after the account’s own environment lines: in Gizai’s runs Claude Code neither reads nor writes its memory folder, whatever its settings say. Codex and Gemini keep no such folder.

Switches

  • Use memory in an agent’s form (on by default): off, its runs get no Memory section and its learned lines are not kept (for the Team Lead: no notes in chat and board checks either).
  • Shares memory with in an agent’s form, under Use memory (Its own folder by default): the agent whose folder it shares, never the Team Lead (see Agents that share a folder). For the Team Lead it is off: it keeps its own notes in Team Lead/.
  • Settings → Runs → Use memory (on by default): off for every agent. The Team Lead’s memory tools still work.
  • Settings → Runs → Ask the Team Lead first (on by default): off, an agent’s question puts its card in the Inbox at once.

The Memory page

The sidebar’s Memory section, under Agents, opens it: the Team Lead first (by its name; it opens every note: its own, the shared folders and every agent’s folder), then each other agent (only its own folder; an agent in a group the group’s folder, titled like “Shares Backend Agent’s folder”), each with how many notes it opens. With no Team Lead yet it shows Shared notes and Set up the Team Lead. Routes: #/memory (every note), #/memory/shared, #/memory/agent/<agent id> (every agent in a group opens the group’s folder), each with a note’s id after it to open that note.

  • Files (left): the folder tree, folders before notes, by name; it remembers which folders are open (this computer). New note, New folder (a folder exists once a note is in it: until then this computer keeps it), rename (double-click, F2 or the pencil; a note or a folder inside a memory folder, never a memory folder itself), and drag a note or folder onto a folder to move it. Moves and renames rewrite the links to the notes, as memory_move does.
  • Search above the tree: words, "phrases", path: and tag: (as the Team Lead’s memory_search), with the matching line and the match marked. An agent’s page searches only its folder. Notes are also in Ctrl+K.
  • The note (centre): Read shows it with its links working ([[Note]], [[Note#Heading]], [[Note|text]]; dashed when no note has that name yet: a click offers to make it), ![[Note]] (or ![[Note#Heading]]) shown in place, and KADE-12 as a chip that opens the card. Resting the mouse on a link shows the note. Edit is the doc editor, with its versions and conflict handling: [[ lists the notes (then # their headings, | their aliases), links are styled, and Ctrl+click (Cmd+click on macOS) opens a link or a card. Read or Edit is kept.
  • The panel (right; its sections fold and stay folded): Backlinks, the notes that link here and, under Unlinked mentions, those that name this note without a link, each with Link (it makes that place a link and saves that note); Outgoing links, also those that find no note yet (Make it); Outline (a click goes to the heading); Properties as a small form (each change rewrites that line and saves a version); Tags, every tag of the page’s notes with how many have it (a click shows only those notes in the tree); History.
  • New note asks for a type (note, decision, lesson, standard, workflow, client, project, deployment, dependency), a title and a folder (the type’s folder by default) and starts the note from that type’s template: its properties and a few headings.
  • With no note open: Recently changed, the notes by their last version, newest first, with who wrote it (you, an agent, a person) and the run’s card when a run did, filtered by Everyone, Agents or You; or, with no notes yet, what memory is.

The graph (GA-69)

Notes | Graph at the top of the Memory page switches to the graph of the page’s notes and what they link to and name (#/memory/graph, #/memory/shared/graph, #/memory/agent/<agent id>/graph): an agent’s page or the shared page leaves out the other folders’ notes and the cards, agents and missing notes only those name. With a note open, Open local graph (next to the panel’s button) shows that note and its neighbours in the panel’s place, and follows the note that is open.

  • What it shows (src/lib/graph.ts, buildGraph): each note is a dot, each link a line: [[wikilinks]] and embeds, card references (KADE-12), @mentions, the @ picker’s links and the client: and project: properties. A dot grows with its links. A link to a note that doesn’t exist yet ends at a dim dot. The cards, projects, clients, agents and people notes name are dots of their own shape and colour, and tags are dots when Tags is on.
  • Using it: pointing at a dot lights it and its links up in the blue accent and dims the rest; a click opens it (a note; New note for a dim dot; a tag’s notes in the tree; a card’s, project’s, client’s or agent’s page). Drag a dot and the layout follows; the wheel zooms and dragging the background pans; labels fade in as you zoom. The keyboard: the arrow keys go from dot to dot and list that dot’s connections, Enter opens it, + and - zoom and 0 fits the graph in view. The local graph lists its note’s connections under it.
  • Settings (the panel over the graph’s corner, kept on this computer like the Memory page’s other settings, the global graph’s and the local graph’s each their own): Filters, a search like Memory’s (words, "phrases", path: and tag:; a matching note keeps what it links to), Tags, Orphans, Existing notes only, and each kind of dot; for the local graph also its depth (1 to 5) and incoming and outgoing links. Groups: a note gets the colour of the first group whose query it matches; it starts with one group per top folder. Display: arrows, text fade threshold, node size, link thickness, and Animate, which replays the graph growing in the order the notes were made. Forces: centre, repel, link force, link distance. The restore button puts them back.
  • The look: the app’s background and fonts, grey dots, thin low-contrast lines, the accent for what you point at and the open note; group and kind colours come from a calm palette without teal or magenta. The layout is d3-force (ISC licence) and settles in a couple of seconds; with reduced motion it is worked out at once and doesn’t move.

Not yet

An export to a folder for Obsidian, deleting notes, a tool for task agents to ask in the middle of a run, semantic search, a review pass. Notes an agent kept in its CLI’s own memory (like Claude Code’s memory folder) are not moved over. The graph (GA-69), an export to a folder for Obsidian, deleting notes, a tool for task agents to ask in the middle of a run, semantic search, a review pass.

Edit on GitHub (opens GitHub)