durmem keeps your agents on track.

Tutorial 03: Set up project memory

This tutorial prepares the palmerpenguins repository for project memory: who authors facts, which project they belong to, and how a later session finds them. Later coding-memory tutorials build on it.

Complete Tutorial 00, Tutorial 01, and Tutorial 02 first.

Three meanings of "workspace"

The word appears in three places. They are related but not the same thing:

Start here: make loom_demo the session default

YouLoad the configured store named loom_demo and make it the default for this session only. Confirm the effective session default, and do not edit ~/.loom/stores.toml.
AgentThe agent connects to the existing loom_demo store and changes only this session's default.
Resultloom_demo is now the default for this session. Persistent configuration was not changed.

1. Verify the tutorial repository and store

Continue in the palmerpenguins repository you opened in Tutorial 00. If it is not the current harness workspace, return to Tutorial 00 and complete its first step.

The repository says which work a memory belongs to; the store says where it is kept. Verify both before creating facts so later sessions read from the same place.

YouSummarize this repository and describe the effective session-default store before we make changes.
AgentThe agent inspects the repository and describes the effective store, confirming it is loom_demo. It reports what the store says now rather than assuming earlier counts.
ResultThis is a small Python package. Loader code is under palmerpenguins/, bundled CSV files are under palmerpenguins/data/, and tests are under tests/. loom_demo is the session's practice store; its description confirms the coding domain and that the store is reachable.

If loom_demo is missing, sign in again with durmem login (for a private server, durmem login --base https://durmem.ai) and stop here if it is still missing. Do not use an unrelated store just because its name looks close.

YouCreate a local branch named loom_demo for tutorial changes.
AgentThe agent creates or switches to the local loom_demo branch without changing a remote branch.
ResultThe local loom_demo branch is ready. Git will record source changes; the loom_demo store will hold durable agent memory about the work.

2. Resolve your author identity

durmem attributes every fact to a real author, so a shared store stays trustworthy when several developers use it. The author identity comes from git, not from a name you type.

YouResolve my GitUser identity for durmem from this repository's git config, and make sure the matching GitUser exists in loom_demo so my facts can be attributed to it. Create it if it is missing.
AgentThe agent runs git config user.email, then saves GitUser("<that email>") in loom_demo. If the node already exists, the save returns the same fact rather than a duplicate, so rerunning this step is safe.
Resultgit config user.email returned dev1@gmail.com. GitUser("dev1@gmail.com") exists in loom_demo. This is masked sample output; in your run, the node and every author edge use the email git actually returned.

An edge can point only to a node that already exists, which is why the identity node comes before any fact that names its author.

Saving a fact that already exists returns the existing fact and leaves its original author unchanged. If a tutorial fact was saved earlier under another author, the agent should say so rather than claim it was re-attributed.

If git config user.email is empty, belongs to a CI system, or is otherwise not the identity you intend, fix it before saving anything. A wrong email creates a second author that never matches your real history.

3. Build the scope chain

Tutorial 01 recalled memory by naming a project, and that is all a first recall needs. Coding work benefits from more structure: a fact about one repository should also see the rules that apply to its whole project or organization. durmem does this with a scope chain of four nodes, each PartOf the next:

Repo("palmerpenguins")
  PartOf → Project("palmerpenguins")
    PartOf → Workspace("palmerpenguins")
      PartOf → Organization("loom-tutorials")

A fact is filed at one node with an InScope() edge. A read at a node also includes facts filed at its ancestors, so a repository-level read sees project-, workspace-, and organization-wide facts. Reads follow PartOf upward only: reading at Organization("loom-tutorials") does not return facts filed under the project below it. File each fact at the narrowest node that fits, and read from the node where you are working.

YouDerive the repository name from the configured Git remote. In loom_demo, make sure Repo("palmerpenguins") exists and is PartOf Project("palmerpenguins"), which continues through Workspace("palmerpenguins") to Organization("loom-tutorials"). Verify the complete chain.
AgentThe agent creates any missing nodes from the top down, then adds any missing PartOf link. It adds a missing link to an existing node directly, because saving the node again would not add the link. Finally it reads the chain back.
ResultThe verified chain is Repo("palmerpenguins") → Project("palmerpenguins") → Workspace("palmerpenguins") → Organization("loom-tutorials") (created on a first run; unchanged on a rerun).

Then tell future sessions where they are. Without this, a new agent may infer the repository name but miss the project, workspace, and organization, and its automatic reads would return only repository context:

YouAdd only the line loom-scope: project=palmerpenguins workspace=palmerpenguins org=loom-tutorials to this repository's existing root agent guidance. If none of AGENTS.md, CLAUDE.md, or CODEX.md exists at the root, create AGENTS.md containing only that line.
AgentThe agent keeps all existing guidance and adds the one loom-scope line.
ResultThe root guidance now carries the scope coordinates. No other guidance changed.

4. Optional: map this workspace to loom_demo

So far each tutorial session has started with a prompt that makes loom_demo the session default. A workspace mapping makes that choice persistent for this one workspace. It is an explicit opt-in that edits your private ~/.loom/stores.toml. It is optional for ordinary coding, but the hook exercise in Tutorial 06 requires it, so do it before that tutorial; otherwise keep the per-session prompt.

YouIn my private ~/.loom/stores.toml, add or update only [workspace.palmerpenguins] with loom-coding = "loom_demo". Do not change the top-level default or any other mapping, and do not show me the file's contents.
AgentThe agent edits only that one mapping and confirms what changed without printing the file.
ResultCoding memory for the palmerpenguins workspace now goes to loom_demo in future sessions. The top-level default and other mappings are unchanged.

To undo it, ask the agent to remove only that [workspace.palmerpenguins] entry.

5. See what is already in the store

Before saving project facts, ask for a bounded view of the whole store. It shows both the data you expected and anything you did not know was there, without letting one large type flood the answer.

YouIn loom_demo, display up to 5 current items for every populated type in this store.
AgentThe agent reads the store's current facts, groups them by type, and shows at most five items per type. When a type has more than five, it reports the total so nothing is silently dropped.
Result
Decision (2):
  - small reviewed tutorial changes before live deploys
  - use the existing notification service for invitation emails

Directive (2):
  - ask before pushing origin main
  - keep access bundles local

GitUser (1):
  - dev1@gmail.com

Goal (1):
  - ship a private beta by September 30 [critical]

Organization (1):
  - loom-tutorials

Project (3):
  - durmem practice notebook
  - loom_demo
  - palmerpenguins

Repo (1):
  - palmerpenguins

Roadmap (2):
  - finish invitation emails before the beta [done]
  - publish runnable onboarding demo for new agents [in_flight]

Workspace (1):
  - palmerpenguins

Read this as "the store includes at least these", not as an exact report. The Directives, the onboarding Roadmap item, and the reviewed-changes Decision are sample facts the store started with, under Project("loom_demo"). The Goal, the invitation-email items, and durmem practice notebook come from Tutorial 01. The identity and scope nodes come from §2 and §3. Counts grow as you work through later tutorials, and a rerun shows facts from earlier passes.

This view shows only populated types. Tutorial 04 shows the full list of declared types, including ones with no facts yet. To see only one project's facts, ask for that project explicitly.

6. Takeaways