Memory
Memchentic keeps long-lived knowledge in spaces. Every memory is one of two kinds: an entry or a guide.
Kind |
In plain terms |
|---|---|
Entry |
Something worth remembering — a fact, preference, decision, or lesson |
Guide |
Something worth following again — standing advice for a recurring situation |
They live in the same places and share the same privacy rules. The difference is the job each one is for.
The same idea can show up as both when you want the record and the playbook (for example a decision you made, plus the habit you want next time).
Spaces
Memories belong to a space: your private personal space, or an optional shared group. Personal is the default. Shared groups are covered in Groups.
Entries
An entry is a durable record. Save one when the important part is what is true, what you chose, or what you learned.
Good entries tend to:
Still matter after the current conversation ends
Save someone from rediscovering the same hard-won detail later
Name something concrete — a preference, a decision, a root cause, a quirk
Skip chatter, unfinished todos, raw dumps, guesses, and secrets. Skip things that are already obvious without storing them.
Entry types
Every entry has a type. The type is a label so you can filter and scan memories more easily — it does not change how search works under the hood.
Type |
Meaning |
Example |
|---|---|---|
|
A stable truth |
“Production publishes the GUI on port 18080.” |
|
How someone wants work done |
“Prefer short answers unless detail is asked for.” |
|
A choice and why |
“Docs ship as their own image, separate from the app.” |
|
A standing always / never rule |
“Never commit unless asked.” |
|
A correction after a mistake |
“Hard-cut API changes — no legacy shims.” |
|
A non-obvious lesson |
“The test database is separate from the live one.” |
|
Anything that does not fit cleanly above |
A short durable scratch note |
A guide is its own kind of memory, not an entry type. If what you need is reusable advice rather than a labeled record, use a guide.
Guides
A guide is reusable advice. Save one when the important part is what to do next time — especially “when this happens, do that, and avoid the other thing.”
Good guides tend to:
Apply to more than one incident
Stay useful without rereading the original conversation
Get stronger when the same advice is confirmed again, instead of spawning near-duplicate copies
A natural shape looks like:
When this situation comes up:
do this
Avoid that
Optional context: why this advice stuck
When similar guide content is saved again, Memchentic updates the existing guide and raises its confidence. Higher confidence means that advice ranks more strongly when you search later.
Choosing entry or guide
If you mainly need… |
Choose |
|---|---|
A record of what is true or what was decided |
Entry |
A playbook for a situation that will come up again |
Guide |
Both the record and the playbook |
Both |
Something temporary, unverified, or secret |
Neither |
How search ranks memories
When an agent asks memchentic a question, it does not get “the newest memories” or “the closest vector match.” It gets a short list ranked by how well each memory matches the question, adjusted for how fresh it is and how often it has been reinforced and used. Memories that nobody uses expire on their own, so the store does not fill up with stale notes.
This page shows the exact formula, so you can see why old knowledge still surfaces when it matters, why new knowledge is preferred when matches are close, and why the result list stays short instead of filling up with noise.
The pipeline at a glance
Question ─┬─> Meaning match ──┐
│ ├─> Fuse rankings ─> Adjust for freshness
└─> Keyword match ──┘ and reinforcement
│
v
Short ranked list
Filter. Only memories in spaces you can see are considered. Memories past their expiry date are skipped. Optional filters (type, tags, path, repo) narrow it further.
Find candidates two ways. One list ranks memories by meaning (semantic vectors). A second list ranks them by words (Postgres full-text search, with titles weighted above bodies).
Fuse. The two lists are combined into one score per memory.
Adjust. That score is multiplied by freshness, path alignment, confidence (for guides), and usage.
Return the top few. Default 20 results; never more than 100.
The formula
For a memory \(m\) and a query \(q\):
Each piece is explained below.
Match: reciprocal rank fusion
memchentic ranks candidates by meaning and by keywords separately, then fuses the two rankings (not the raw similarity numbers):
\(\text{rank}\) starts at 1 for the best hit in each list. A memory missing from a list adds nothing for that list.
\(k\) is
RRF_K(default 60). A larger \(k\) flattens the gap between rank 1 and rank 10.
Why this matters: a memory that is both about the right thing and uses the right words appears in both lists and scores roughly twice as high as a memory that only matches one way. Paraphrased questions still find the right memory through meaning; exact names, error strings, and file paths still win through keywords.
Freshness: gentle recency decay
Age is measured from the memory’s last update (or creation, if never edited).
\(H\) is
SEARCH_RECENCY_HALF_LIFE_DAYS(default 30).
Age |
Freshness (H = 30) |
|---|---|
Today |
1.00 |
30 days |
0.50 |
90 days |
0.25 |
180 days |
0.14 |
1 year |
0.08 |
The curve drops quickly at first and then flattens. Old memories are discounted, never zeroed out. An old memory that is a much stronger match can still outrank a new, weak one.
Editing a memory (for example with revise) resets its age. Keeping a
memory accurate keeps it current.
Path: work-location alignment
\(B\) is SEARCH_PATH_BOOST (default 0.15). Memories saved with a
path_hint are favored when an agent searches from that part of a codebase.
Confidence: reinforced guides
A new guide starts at \(c = 1\). Every time an agent writes nearly the same guide again, memchentic merges it into the existing guide and raises \(c\) by 1 instead of creating a copy. A guide confirmed five times gets a 1.5x boost. Advice that keeps proving useful rises; one-off advice does not.
Usage: memories people actually recall
\(n\) is how many times the memory has been recalled: returned by a search or opened. Repeated hits within a few hours count once.
\(W\) is
MEMORY_USAGE_SCORE_WEIGHT(default 0.05).
Recalls |
Usage boost |
|---|---|
0 |
1.00 |
5 |
1.09 |
50 |
1.20 |
500 |
1.31 |
The logarithm keeps this gentle. A popular memory gets a nudge, but it cannot outrank a far better match just because it is popular. Being recalled does not reset freshness. Only editing does.
A worked example
Four memories match the same question:
Memory |
Matches |
Age |
Kind |
|---|---|---|---|
A |
Rank 1 by meaning and by keywords |
10 days |
Entry |
B |
Rank 3 by meaning only |
1 day |
Entry |
C |
Rank 2 by meaning and by keywords |
1 year |
Entry |
D |
Rank 3 by meaning and by keywords |
45 days |
Guide, confidence 4 |
With the defaults (\(k = 60\), \(H = 30\)):
Memory |
Match |
x Freshness |
x Confidence |
Score |
Place |
|---|---|---|---|---|---|
A |
2/61 = 0.0328 |
0.75 |
1.0 |
0.0246 |
1st |
D |
2/63 = 0.0317 |
0.40 |
1.4 |
0.0178 |
2nd |
B |
1/63 = 0.0159 |
0.97 |
1.0 |
0.0154 |
3rd |
C |
2/62 = 0.0323 |
0.08 |
1.0 |
0.0025 |
4th |
What this shows:
A wins because it is both a strong match and recent.
D is older than B and slightly weaker, but it is a guide that has been confirmed four times. Reinforcement keeps it above a brand-new, one-sided match.
B is the newest memory, but it only matches one way. Freshness alone does not put it on top.
C is a strong match but has not been touched in a year. It sinks instead of crowding the top results. It is still there: a more specific question, or a quick
reviseto confirm it is still true, brings it back.
Why this works long-term
Large, long-lived memory stores usually fail in one of two ways. They either forget useful old knowledge, or they bury the answer under years of stale notes. This formula avoids both.
Problem |
How the formula handles it |
|---|---|
Old but still-correct knowledge disappears |
Freshness never reaches zero. A strong match survives age. |
Stale notes crowd out current ones |
Freshness halves at 30 days and keeps falling. Close calls go to the newer memory. |
Paraphrased questions miss |
The meaning list finds memories without matching words. |
Exact names and error strings get fuzzy results |
The keyword list rewards exact terms. Titles count more than bodies. |
Repeated advice piles up as duplicates |
Guides merge and gain confidence instead of copying. |
Repeated facts pile up as duplicates |
Near-identical entries are refused at write time ( |
Temporary notes linger forever |
Every memory expires unless it keeps being used. Agents give scratch notes short lifetimes. |
Popular knowledge gets cleaned up by mistake |
Each recall renews the expiry, and usage nudges the ranking up. |
Agents flood their context |
Results are capped (default 20, max 100), and each one is a short digest until opened. |
Other teams’ notes leak in |
Only spaces you belong to are searched. See Groups. |
Tuning
All knobs are environment variables on the application. See Environment Variables for the full list.
Variable |
Default |
Turn it up when |
Turn it down when |
|---|---|---|---|
|
|
Knowledge stays true for months (policies, architecture) |
Facts change weekly |
|
|
You want matches across both lists to matter more evenly |
You want top-ranked hits to dominate |
|
|
Path-scoped memories should win harder |
Paths are noisy or unused |
|
|
Too many legitimate variants are refused |
Near-copies are slipping through |
|
|
Humans browse results in the UI |
Agents waste context on extra results |
|
|
Frequently used memories should rank higher |
Popularity is skewing results |
|
|
Knowledge is slow to be revisited |
The store grows faster than it is used |
|
|
Memories used occasionally should stick |
Only frequently used memories should stick |
|
|
Hot memories should live longer (or |
Retention policy requires periodic review |
A good starting point for a large organization is a half-life of 60 to 90 days, with a lower default limit (around 10) for agent clients.
Lifetime: sliding expiry
Ranking (above) decides what comes first. Lifetime decides what is still there.
Every new memory gets an expiry date:
The saving agent passes |
Expiry |
|---|---|
Nothing |
90 days from now ( |
|
14 days from now |
|
Never |
|
That exact time |
Agents pick the lifetime when they save: a short one for a temporary workaround, the default for an ordinary fact, permanent for a standing rule.
Each recall renews a live memory. When a memory is returned by a search or
opened, its expiry moves out to at least 90 days from now
(MEMORY_TTL_EXTEND_DAYS):
\(E\) is
MEMORY_TTL_EXTEND_DAYS(default 90).\(M\) is
MEMORY_MAX_TTL_DAYS(default 730, about two years;0removes the ceiling).Renewal never shortens an expiry the agent chose.
Repeated recalls within
MEMORY_TTL_TOUCH_DEBOUNCE_HOURS(default 6) count once, so one busy session cannot keep junk alive.Writing the same guide again also renews it.
What happens at expiry. An expired memory drops out of search, browse, and
the other recall tools. It is not deleted: you can still list it with
include_expired, open it by id, and bring it back with revise (set a new
expires_at or clear the expiry). Recalling an expired memory does not revive
it on its own.
The result: a memory that people keep using stays indefinitely (up to the ceiling), and a memory nobody has needed for three months leaves search without anyone having to clean it up.