Memory Maintenance
SkillFiles & storageUse when curating the persistent file-based memory (…/memory/MEMORY.md + per-fact *.md), structuring/grouping the index, removing cruft or duplication, fixing stale index hooks, trimming a bloated index line, or ensuring open action-items in memory are also tracked in 00_07. The HOW lives in .claude/prompts/memory_housekeeping.md; the memory FORMAT standard lives in the system prompt (don't restate). The 17 curation traps, scout counts run low, a half-home may be a duplicate, machine dedup is capped at verbatim, an inventory that NAMES a home has usually not opened it, are indexed here one line each and written in full in this skill's traps.md, which loads on demand: open it before any curation VERDICT (consolidating a class, pricing a duplicate, declaring something homeless, reporting a corpus number). Iron rule: NO AMNESIA, preserve wins over cleanup. Examples: \"почисти память\", \"поструктуруй memory\", \"повидаляй дублі в памяті\", \"memory housekeeping\", \"чи всі to-do з памяті є в 00_07?\"
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Memory Maintenance skill
What this skill tells your AI
The instructions your AI receives, as published by alexey-lukin/silken_net in .claude/skills/memory-maintenance/SKILL.md and read by ahel’s review.
Executable playbook for keeping the persistent memory (~/.claude/projects/…/memory/) clean, structured, dedup'd — without amnesia. This skill is the HOW; it does not restate the memory FORMAT (frontmatter / types / Why+How-to-apply / [[<slug>]] links / one-fact-per-file — that's in the system prompt), nor the live state (that's in the memories themselves).
📖 The method lives in one place (don't restate it here)
Full step-by-step playbook + founder's principles + the zero-loss scripts → .claude/prompts/memory_housekeeping.md. Read it before acting.
⚖️ Where this boundary actually runs, ratified 2026-09-08 after the pair was re-litigated once. «One home» here means the METHOD, not every mechanism the method leans on — and the two split by the MOMENT they fire, never by topic: the prompt carries what fires while you are deleting (verify-before-delete, what is safe to trim, whose home must exist first); traps.md carries what fires while you are pricing a VERDICT (how far a machine measure of duplication can be trusted, and its measured numbers). A rule that fires at BOTH moments legitimately has a carrier at both — that is not the «same warning in two homes» debt, because no single reader at a single moment needs both halves. 🔴 The test, when the pair looks like a duplicate: name the reader and the instant. If one reader at one instant needs only half, the halves are two carriers; if the same reader needs both, one of them is a restatement and goes. Sister to [[reference_deep_archival_prompt]] (00_07 cement) — same "the prompt is the home, the skill just points" pattern as ssot-maintenance.
Three modes: (1) housekeeping (this skill + the prompt — de-cruft, structure, stale-hooks, action-items→00_07); (2) 4-way memory-sync — a per-section pass bringing memory ↔ domain-skill ↔ canon ↔ 00_07 to one truth (ROUTE-not-restate, fix drift on BOTH surfaces, write gaps). The sync recipe (fan-out READ-ONLY agents + fable-holistic) lives in [[project_memory_sync_program]]; the §00–§08 cycle closed 2026-07-18. (3) class-home consolidation — a theme scattered as a side-note across 15–35 files, each time in a DIFFERENT vocabulary, gets one home; grep cannot find it by construction, so the inventory is READ-based fan-out. Built in waves, each one paying part of the previous wave's phase-2 debt; the 7-step recipe, its traps and the ledger of still-PARTIAL classes all live in [[log_perimeter_prep]] — read it BEFORE consolidating another. Never keep that tally here, and no longer look for it in the tracker: DOC-T.59 carried it until 2026-08-04, when the item closed, its body was collapsed and the ID went to §🗄️.
Traps before you consolidate — each one cost a wave
Bodies live in traps.md (read it before any curation VERDICT — consolidating a class,
pricing a duplicate, declaring something homeless, reporting a corpus number). Below is one
generated line per trap: the line is the CARRIER, meant to stop you mid-action; the mechanism,
the measurement and the provenance are in the companion. Numbering is append-only — cited as
«пастка (N)» from 10 memory files and docs/00_07.
- Scout counts run LOW — and the direction is set by WHAT is counted, not by who counts
- A «half-home» may be a duplicate — compare the two texts before believing they are coverage
- One-way strings fake homelessness — a home that CITES you is a home you already have
- Machine dedup is capped at VERBATIM, and on a bilingual corpus the gap is an order of magnitude
- Declare the UNIT first — «debt weight» and «what an excision returns» differ in the SIGN
- Mechanism ⊥ frame — «does this have a home» is TWO questions, and the homeless one is almost always the FRAME
- An excision that TRANSLATES pays the bytes back — and looks like honest work while doing it
- Measure the RECEIVER's headroom, not just the source's debt
- «All three surfaces» is FOUR — the index is one of them
- Ask whether the clause has TWO homes, not whether it has one
- A
⊥mark blesses the DIVERGENCE, not the missing router — it does not exempt a clause from phase 2 - The claims that rot are almost exclusively SELF-LOCATION claims — and no sweep of the file that carries them can see it
- The verdict ADDRESS-vs-SCOPE is decided by the source's GENRE, so read the genre before you read the pair
- Every instrument you write to MEASURE this corpus will strip the token that discriminates — verify by reading the top hits before you report the count
- A
TO-GITverdict needs THREE measurements, and the third is the one that manufactures work when skipped: does git ALREADY SEND readers to the memory copy - A restatement that SENDS can still LIE — so the redundancy question has a second axis, and only the second one is dangerous
- Opposed frames do not protect against a shared READING habit — and the two costliest misses of a curation pass both arrived as a home that is not one
- Editing memory through
Bashbypasses BOTH of its carriers silently — the growth gate and the auto-commit are hooked onEdit|Write, and nothing announces their absence - Дзеркало пастки (18): авто-коміт робить ВАКУУМНИМ будь-яке порівняння «до/після», побудоване на робочому дереві — і брехня тут іде в бік «це не я»
When to use
- Structuring / grouping
MEMORY.md(by kind: 👤User / 🛠Feedback / 📚Reference / 📦Project, + sub-themes). - Removing memory cruft / duplication; trimming a bloated index hook (detail belongs in the file).
- Fixing a stale index hook (drifted from its file).
- "Is every open to-do/check in memory also in 00_07?" → migrate the gaps.
- Integrity check (1:1 index↔files, no broken/orphan).
Core principle — NO AMNESIA
🧭 The question that finds the right cuts — ask what FEIGNS fullness, never what to delete (founder frame, 2026-08-22; the kenosis axis this practice already runs on the hot path). Classic de-cruft hunts verbosity, so it is structurally blind to the expensive class: a form that is EMPTY while looking complete, and usually SHORT. Measured in one session, three findings none of which a wordiness pass would have surfaced — a work QUEUE that had stopped being a queue and only drove readers at finished work; a PROHIBITION whose stated ground had evaporated (the ruby pair it named no longer reproducible); a reference_* STUB whose whole justification («the skill carries no state pointer») had been closed months earlier. All three read as healthy content. So the cut criterion is not «is this too long» but «does this form still do the work its shape claims». ⚠️ And the frame is a foundation, not an instrument: it says why a cut is right, never whether a fact is still true — that is what the artefact and grep are for.
Preserve beats cleanup. Before removing ANY content, verify it lives elsewhere (the file, git, canon, 00_07). Improve/relocate, never delete what's valuable. When "remove cruft" conflicts with "don't lose what's needed" → keep. A well-curated memory's housekeeping is mostly de-bloat + structure + stale-hook fixes, not mass-deletion — say so honestly, don't manufacture deletions (the ssot-maintenance "don't manufacture moves" lesson, applied to memory).
Type-routing — which surface a fact belongs to
Memory is a ROUTER, not a second copy: the absolute context is re-assembled from scratch every task (memory → skills → canon → code), so anything you would re-read from canon or code anyway is not a memory fact. Route each piece by its TYPE, at the moment you write it — this is a write-time question, and it is the one the index is actually consulted for.
| the fact is… | its home |
|---|---|
| operational HOW — generators, CLI recipes, code inventories | the domain skill |
| shipped WHAT, or a frozen decision | canon NN_NN (+ a 00_07 ID while it is still open) |
| live state · cross-domain trap · lesson · the founder's "why" | memory |
| a portable rule about how the WORK gets done | the playbook someone reads before doing it |
Two halves make this operational rather than decorative.
Elevate, then point. A meta-lesson recurring across domains gets ONE home and every instance points at it. The failure mode is not a missing home but a SECOND one — both links resolve, only the prose disagrees, so no gate can see it. Before building a home, ask which part is actually homeless — instance, mechanism, remedy, or FRAME — because it is nearly always the frame, and grep finds instances (trap 6).
Routing audit. Every project_* file must route somewhere real: canon, a live tracker ID, code, a skill, or an inbound string. A file routing nowhere is an episode, and an episode with no string dies whatever the index says. ⛔ Do not rebuild the machine form of this — it was built and measured: 0 true findings against 2 false out of 55, because the set of legitimate homes is open-ended. It stays a reading discipline on purpose. That verdict is not local to this rule: where the discriminator has a form, the yield is near zero and a carrier is cheap; where the yield is large, there is no form. Check which half you are in before proposing a gate.
A PLAYBOOK has a trigger of its own, so audit it by asking what fires its READER — not what its title is about. Measured 2026-08-08 on the housekeeping prompt: of 48 durable lessons only 19 were strictly housekeeping-scoped; the rest fired at memory-write · agent-spawn · gate-patch · measure · big-edit · founder-push, i.e. precisely at moments when that file is not loaded and nothing loads it. A lesson stored in a playbook whose trigger it does not share is stored nowhere — the surface looks maintained and the rule never arrives. Consequence for writing: before adding a lesson to any playbook, name the event that must interrupt someone, and put it where a reader stands at THAT event (the gate's own message text is often the strongest carrier — it is the one line that reaches the person mid-action). Consequence for the prompt specifically: §Durable there is now housekeeping-scoped by construction, and each family carries a 📤 router naming where its evicted lessons went — do not put an agent-spawn or gate-patch lesson back into it. ⚠️ Two exceptions survived the pass on purpose and both are instructive: a per-file proposal recipe that had zero hits anywhere else, and a classification that two other files explicitly route INTO the prompt for. A "home" that cites you is not a home; check the direction of the string before you cut.
ORDER, because the debt is written in PARALLEL with git — not after it. Measured across four files: in one rule-home five of six debtor sections were written the SAME DAY as the canon paragraph they duplicate, by the session that created it. So the memory is not lagging the repo and no editorial pass can fix it — both texts are produced in one sitting, and the second one is the cheap one. Write the canon / skill / gate FIRST, verify it landed, and then write only the SEND into memory. An excision afterwards merely removes what the procedure should never have produced, and it costs the READ bar every time. The other debt shape does need an excision, and its tell is temporal: a home one to two and a half months OLDER than the memory's last write means the home absorbed the content and the memory simply never shrank.
The gate is the home of the mechanics — not this file, not the prompt
.claude/hooks/memory_gate.sh runs the whole step-1 battery (--audit, exit 0 = clean) and rides PostToolUse on every write into the corpus, so it fires at the moment a wall gets built rather than when someone remembers to clean. Found a new blindness class? Patch the script — it is live on the next write, and the separate "carry the lesson into the gate" step that failed before no longer exists. 🔴 But that instruction was missing its other half for weeks, and the omission is expensive: the gate carries a --selftest battery of 40+ cases with positive AND negative controls, and it is CI-gated (docs.yml). Neither this file nor the prompt said so, so a curator who obeyed the central prescription — patch the gate — would break CI without knowing why, and would not know that the norm here is to ship a patch WITH its pinning case, mutation-verified (remove the fix, prove exactly that case reds). Run it before and after every patch; a case that passes both ways is testing nothing. Beside the battery it carries diagnostic modes that deliberately sit OUTSIDE --audit (read the case block for the current set — naming them here is the list-by-example rot warned about below). The rule deciding which is which: a check whose live yield is a handful belongs IN the battery; one whose yield runs to dozens is a worklist, and folding a worklist into --audit makes EXIT 1 permanent, which trains the reader to skim the one stance that must stay loud. A worklist mode is therefore not a weaker gate — it is the same finding addressed to a session that has time for it. Thresholds are curated constants inside it; the corpus is outside git but the gate is not, so a bump is a visible decision.
The loop (detail → prompt)
1. INVENTORY memory_gate.sh --audit — run it, do NOT enumerate its axes here: a
list-by-example rots with every axis added, while a pointer at the
live source stays true. Then run the SEPARATE modes: the `case`
block is the roster, and it is short enough to read every time.
⚠️ This paragraph itself rotted, in the direction that costs most
(measured 2026-08-06): it named OVERLAP and --oneway as the two
axes "OUTSIDE --audit", while `overlap_check` is called INSIDE the
--audit battery and no `--overlap` mode exists at all — so a reader
following this text would invoke nothing and read the silence as
"phase-2 debt unmeasured". The enumeration was added two sentences
after the rule forbidding enumeration, which is the whole lesson:
READ the case block, never this list. What is worth carrying is
not WHICH modes exist but WHY some are split out — a check whose
live yield is a handful belongs in the battery; one whose yield
runs to dozens is a worklist, and folding a worklist into --audit
makes EXIT 1 permanent, training the reader to skim the one stance
that must stay loud.
2. INDEX=HOOKS trim any bloated index line — but VERIFY the detail is in the file FIRST.
3. STRUCTURE group MEMORY.md by kind via a verbatim-reorder script; prove zero-loss
(sorted entry-set diff == IDENTICAL).
4. DE-CRUFT only truly-dead content; verify-before-delete; preserve lessons/decisions/
open-items/links. Don't gut the big history file without explicit OK.
5. ACTION→00_07 any open to-do/check/follow-up not in 00_07 → add it (correct §-home;
section-home guard) + a "Tracked in 00_07: <ID>" back-pointer in the memory.
6. STALE-HOOKS refresh hooks that drifted from their file's state.
7. REPORT honestly: cleaned / deliberately-kept (no amnesia) / flagged.
Shortened here. Read the whole file on GitHub.
Signals
- GitHub stars
- 22
- Forks
- 1
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
memory-maintenance- Source
- github.com/alexey-lukin/silken_net