| name | llm-context-guideline |
| description | Placement and admission policy for content that enters LLM context; its chapters currently govern the memory store (admission whitelist, the three proof questions, entry form and labeling, canon change rules). Reload in full before touching memory content. |
| user-invocable | false |
Memory Curation Policy
The store manages session context, and context is capability: a model reasons worse as its
window fills, so curation optimizes for the smallest store whose entries still change future
actions. Every entry taxes future sessions through one of three delivery paths: resident topics
inject in full at every master spawn, every other entry adds an index line there, and a topic
query pulls its whole topic. An entry earns admission when the action it changes outweighs the
context it permanently occupies; a surface the reader already reads unconditionally (a prompt, a
skill, the owning repo's docs) wins over the store.
The memory store (~/.charliebot/memory/) is a local git repo of labeled entries: one durable
fact or rule set per file under entries/<topic>/<slug>.md, with front matter restricted to
scope, topic, audience, title and a pure-markdown body.
Sessions only stage candidates (charliebot memory add writes to staging/): a staging
candidate is a free-form capture whose labels are assigned at curation and whose change intent
lives in the body; the canon changes only through user-approved diffs.
This file governs the daily curator AND ad-hoc user-directed promotions: the same admission test
and labeling rules apply in both flows.
Admission test
Admission is judged at curation time, with evidence, never mid-session. The store admits three
kinds of entry, and only these:
- A ruling or preference the user stated.
- A mechanism or fact whose rediscovery would cost a real investigation and that still reads
true a month from now.
- A host, cluster, or account level pointer that cannot be guessed and has no owning document.
Everything else stays out by default; when in doubt, reject and name the candidate in the
report. Knowledge the model derives with no context (general engineering or statistical
reasoning) is never admitted: the cheapest home is the model itself (user ruling 2026-08-26).
Every admit and every revise carries three proof lines in the report, each headed by the
question it answers; a question that finds no answer is the signal to rethink whether the
entry belongs in the store at all, and such a candidate is rejected:
- "When will this be used again, and what will it change?" (the Action line): the concrete
future action this entry changes, named as work that recurs or is already planned in a named
project or stack; a constructed possibility fails the line.
- "Why is the store the cheapest home?" (the Home line): answered by checking the others:
repo-scoped knowledge lives in that repo's own CLAUDE.md or docs; charlie-bot behavior lives
in the master prompt, a skill, config, or the source; incidents and event history live in
LESSONS.md; run results, live state, and receipts live in the run dir or owning session; a
project's experiment verdicts live in its tracker (Linear), not the store (user ruling
2026-08-26).
A project-scoped finding lives under that project's topic or its repo docs; a cluster or host
entry holds only what binds every project there. The Home line also names the reader and the
delivery path that reaches them at the moment the entry changes their action. A reader who
cannot know to query fails the line: the knowledge belongs on a surface they already read.
Residency is the costliest slot, full text in every master spawn: process rules governing every
session hold it; domain conventions live with their domain. When the natural home is obstructed,
fix the obstruction or take another tracked path inside that home; the store does not absorb
another home's content.
- "Is this the most concise expression?" (the Brevity line): the curator trims the
presented text (the new body, or the whole entry after a merge) to the Entry form brevity
bar before presenting, and the answer names what the trim removed, or states the body's
line count when the draft already sat at the bar.
A candidate's text is a claim: verify its figures against the live system before presenting
them. A revise re-verifies the surviving claims of the entry it edits.
A trap claim about shared infrastructure enters only with its root cause named and reproduced
outside the originating session; a fixable obstruction is fixed instead of recorded.
Data cheap to re-obtain on demand lives in session reports and run dirs; the store keeps the
takeaway that tells the reader where to look.
Admission is merge-first and strict
The default action for a passing candidate is merging into an existing entry, a revise
that extends the entry whose theme already covers it, so git diff shows the before and after.
Creating a NEW entry additionally requires both:
a. No theme coverage: no existing entry's theme covers this candidate; check the index
(charliebot memory query --index) before proposing one.
b. Title-honesty: the title honestly describes the entry's whole content after the change.
A title that over- or under-states the body is a reject reason.
The skills boundary
The store holds decision knowledge: facts, rules, and conventions that change what the
reader does next. Step-by-step operating procedures (command sequences, recipes, and their
reference files) live in the owning skill, never the store: reject procedure-shaped
candidates and name the owning skill in the report. Live state under active investigation
stays with its owning system. One home per item: when a rule is admitted to the store, no
skill keeps a duplicate of it.
Labeling: the three axes plus title
Every entry carries scope, topic, audience, and title in its front matter:
- scope in
user | host: user follows the human across machines; host is tied to this
machine (hostnames, local paths, hardware, internal endpoints).
- topic: one entry has exactly one topic, equal to its
entries/<topic>/ directory and
present in the topics vocabulary. The topics vocabulary grows only by user ruling.
Cross-topic content belongs in a resident topic
(workflow, rulings). The resident suffix in topics marks topics whose entries inject in
full at master spawn. Reads are topic-granularity: a query returns the whole topic (audience-filtered), and agents see
topics only, split entries for curation and audience separation, with the topic as the sole retrieval unit.
- audience: comma list, each element in
master | worker, at least one, who receives the
entry's full body at spawn: master spawn gets master-audience entries in resident topics as
full text, others as index lines; worker spawn gets worker-audience entries matching the repo
basename as full text, others as index lines. Both roles: audience: master, worker.
- title: one non-empty line honestly describing the whole entry; it is what index lines and
spawn-injected headings display.
Entry form
One coherent fact or rule set per entry. The title lives in frontmatter; the body is pure
content. Timeless phrasing: state the standing reality. Dates, session ids, commit hashes,
quoted rulings, event history, and case enumerations belong in LESSONS.md. Said once, in one
language, lines 120 columns or fewer; surpass entries may be written in Chinese (user ruling
2026-08-24). Entry prose follows the Writing Style section of
prompts/master.md. Apply the
admission test line by line as well as entry by entry: a line that changes no future action
leaves.
Brevity is part of the admission bar: lead with the action and keep only the mechanism the action
is unintelligible without; receipts, verification notes, and secondary effects leave. Hold a
bullet to about three lines and an entry body to about a dozen; a merge that would grow past that
re-trims the whole entry by the same test.
A measured figure lives in its canonical source (run dir, canon table, ticket); an entry states
the rule and points there.
Environment composition and version facts (package pins, toolchain and interpreter versions,
build and model numbers) never enter an entry: the manifest or config that pins them is the
home, and the entry states the rule and points there.
Machines go by hostname; a role phrase like "the CharlieBot host" re-points when infrastructure
moves. When context changes, revise the entry in place (a capture whose body states the change
stages the proposed new text).
A retired or archived system's content leaves the store outright, entries and lines alike: the
store states standing reality, and LESSONS.md holds the retirement event when it matters.
Commit message prefixes
Curation commits use one of three prefixes so git log enumerates the canon's history:
admit: <topic>/<slug> (<title>): a new entry promoted from staging.
revise: <topic>/<slug> (<title>): an in-place edit of an existing entry (honoring a revises
candidate, including merge-ins).
migrate: <topic>/<slug> (<title>): a format-only rewrite to entry format v2 (moving the
title to frontmatter, splitting both, dropping created/source) with no content change.