| name | refine-memory |
| description | Distill raw chat transcripts into durable, retrievable memory atoms. Use when asked to refine memory, organize past conversations, or consolidate the memory directory (triggers like "refine memory", "ๆด็่ฎฐๅฟ", "ๆ็ผไผ่ฏ"). |
Refine Memory
Distill raw conversation transcripts into retrieval atoms so a future session
recalls what matters by Grep/Read, without re-reading whole transcripts.
This skill is stratified: each layer uses the representation that fits its
precision. Math states what; the tool computes the deterministic parts;
Clojure pins the branching; prose carries the judgment that can't be
formalized. Read top to bottom, then follow ## Procedure.
Locations
The memory directory was given in your system prompt ("Past conversations with
this user live in ..."). Inside it:
sessions/ โ raw transcripts, one markdown file per chat (input, immutable)
refine/ โ distilled atoms, organized by topic, not by session (output)
A second auto-memory system may coexist (MEMORY.md + memory/*.md). It
holds short, recall-injected rules; refine/ holds long-form retrievable atoms.
A fact is authoritative in one system only โ refine/ complements, never
mirrors.
Layer 0 โ Direction (what the output is)
The product is a set of retrieval atoms. An atom is well-formed iff:
atom(a) โบ atomic(a) โง retrievable(a) โง answer_bearing(a)
- atomic โ one fact; the minimal independently writable/retrievable unit.
- retrievable โ found by a plausible future Grep (self-anchoring, or given an
explicit
[anchor: โฆ]).
- answer_bearing โ states a conclusion, not a pointer to where one might be.
If a candidate fails any conjunct, split it, re-anchor it, or drop it.
Layer 1 โ Definitions (precise)
- Input delta (computed by the tool, never by eyeballing mtime):
delta = โแตข turns(sessionแตข) โ seen
- Duplicate (resolve by merging, not appending):
dup(a) โบ โ b โ (refine โช auto-memory) : key(a) = key(b)
- One fact, one home โ
refine/ is a partition: every atom lives in exactly
one file. No copies across files or across memory systems.
- Date by truth, not by session โ
date(a) = becomes_true(fact(a)). A paper's
date is its publication, not the day it was discussed. Tag the discussion date
separately only if it matters (e.g. evaluated 2026-06-17).
Layer 2 โ Mechanics (the tool does this; you don't guess)
scripts/refine_delta.py (path given in your prompt) handles idempotency and the
loop guard deterministically:
prepare --root <memory_dir> โ writes refine/.inbox.md with only new,
non-loop turns, and stages their hashes in refine/.pending.json.
commit --root <memory_dir> โ folds the staged hashes into the watermark
(refine/.distilled.json) and clears the inbox. Run only after a
successful distill, so a failure never loses un-distilled turns.
You never decide "was this already refined?" or "is this a refine echo?" โ the
tool already filtered those out before you see the inbox.
Layer 3 โ Routing (branching, unambiguous)
Each inbox turn routes by the tree below. The leaf predicates are your
judgment; the control flow and the output taxonomy are fixed.
(defn route [turn] ; transcript turn โ disposition + atom type
(cond
(loop-artifact? turn) :drop/loop ; tool pre-filters; this is a backstop
(noise? turn) :drop/noise ; greetings, one-off lookups, tool mechanics
(preference? turn) :keep/preference
(decided? turn) :keep/fact ; decisions, findings, conclusions
(context? turn) :keep/context ; project/domain background explained
(deferred? turn) :keep/backlog ; "next time", "later" โ volatile
:else :review)) ; unsure โ hold, don't force an atom
(defn place [atom-type] ; atom type โ home file (one fact, one home)
(case atom-type
:preference "refine/_user.md"
(:fact :context) topic-file ; merge into the matching topic file
:backlog "refine/_backlog.md")) ; volatile state, isolated from stable notes
Layer 4 โ Judgment (not formalizable โ this is your job)
- Durability โ keep only what a future session would benefit from; discard the
transient. When unsure, route
:review and leave it out rather than guess.
- Anchoring โ if an atom's statement isn't something you'd naturally Grep for,
append
[anchor: <search terms>]. The anchor is the retrieval handle, distinct
from the statement.
- Semantic dedup โ Layer 1 gives the predicate; you supply the similarity call.
Before writing, skim
refine/ and (if present) auto-memory; if a fact is already
homed, update it in place โ never add a second copy.
- Topic naming & merging โ group
:fact/:context atoms into cohesive topic
files; create a new one only when nothing fits.
Layer 5 โ Invariants
- Merge, don't append blindly โ contradictions resolve toward the newer transcript.
- Volatile โ stable โ backlog/pending items live in
refine/_backlog.md, never
mixed into stable topic notes.
- No-op is valid โ if the inbox is empty or held only noise, say so with the
reason; never manufacture edits.
sessions/ is immutable โ never modify or delete a transcript.
Atom format
One atom per line: a self-contained statement, a :type tag, the truth-date, and
an optional retrieval anchor.
## <topic>
- <self-contained fact statement> `:fact` (2026-06-17) [anchor: <terms, if needed>]
Procedure
- Prepare โ run
refine_delta.py prepare --root <memory_dir>. Read the printed
summary and refine/.inbox.md.
- No-op check โ if the inbox is empty, report that (with the reason from the
summary) and stop. Do not run commit.
- Distill โ for each turn in the inbox:
route it, and for kept turns extract
atoms (Layer 0 shape), place them into the right refine/ file, merging per
Layer 4 dedup. Date by truth (Layer 1).
- Commit โ run
refine_delta.py commit --root <memory_dir> to advance the
watermark.
- Reply with a one-paragraph summary of what was added, merged, or skipped.