Documentation

Rule files

The rules that always apply should not depend on a tool call. Memmo compiles approved memory into the files agents read from the repo, in two tiers: a short, budgeted block in each rule file, and a tree of small files holding everything else.

1

Run it

memmo sync                 # write the blocks and the tree
memmo sync --check         # write nothing; exit 1 when the files drift from memory (a CI gate)
memmo ci --rules           # a weekday GitHub Actions job that opens a PR when they drift

sync writes one managed block per file — between <!-- memmo:start --> and <!-- memmo:end --> — and never touches text outside the markers. Run it from the repo root; it finds your package roots (directories with a package.json, pyproject.toml, go.mod, …) on its own.

2

The always-on tier

CLAUDE.md at the root carries project-wide memory; each package gets its own file for the memories scoped to its paths. Blocks are budgeted (about 1,500 tokens at the root, 500 per package) and ordered rules → commands → risks → current decisions → architecture, so they stay a prime rather than a dump. The same block can go to AGENTS.md and .cursor/rules.

3

The memory tree

Everything else goes under .memmo/memory/ (the folder is yours to choose per repo, e.g. docs/memory): README.md (an index with counts), project.md and one file per package area, every approved memory condensed to one line. Linked memories cross-reference each other, every file links back to the index, and each block links to its area file — so an agent reads the area it is about to change on demand. If your .gitignore excludes .memmo/, the sync narrows that rule so the tree can be committed.

4

What goes in

  • Approved memories only; a memory replaced by a newer decision is left out, the current one says what it replaced.
  • Business context stays out unless the repo opts in — it ends up in git history, visible to every contributor.
  • Any memory can be kept out from its card (“Rule files: kept out”).
  • The session briefing skips what the files already carry, so nothing is said twice.

Targets, budgets, the tree toggle and a preview of exactly what will be written live on the Rule files screen in the app.

5

Keeping them fresh with CI

memmo ci --rules writes .github/workflows/memmo-rules.yml: every weekday morning (and on demand) it runs the sync and opens a pull request on the memmo/rule-files branch when the files drift. The reviewer skips those PRs. It needs the same MEMMO_TOKEN secret as the reviewer, and GitHub must allow the job to open pull requests — one of:

  • Repo Settings → Actions → General → Workflow permissions: tick “Allow GitHub Actions to create and approve pull requests”. In an organization that box is greyed out until the same setting is enabled at the organization's Settings → Actions → General.
  • Or skip the org change: store a fine-grained personal access token (Contents + Pull requests write on the repo) as the MEMMO_GH_TOKEN secret — the workflow uses it when present.
6

Custom outputs

Rule files are the built-in preset. Under Outputs in the app you can add your own: a filtered slice of memory, written to any file, in the shape you choose. Pick the memory types, tags, intents or confidence it draws from, a destination path, and a format — rules (the terse block style), reference (fuller prose with tags and paths), checklist (a checkbox per memory), or narrative — a readable document the AI writes from the facts, grounded and cited, for product docs, architecture guides and onboarding. Narrative docs are generated on demand with your own key and cached; memmo sync writes the last generated version. Each output lands either in a repo file (a managed block on the same memmo sync, the text around it untouched) or on a Notion page that Memmo writes directly — the mirror image of a Notion knowledge source. A security checklist at docs/security.md, an architecture reference, a product doc synced to the team's Notion.

A PR is the review moment: when a line looks wrong, edit the memory in Memmo rather than the file — the next sync rewrites the block.