Use 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 ...
Scanned 9/20/2026
Install to Claude Code
npx -y skills add Alexey-Lukin/silken_net --skill memory-maintenance --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Memory Maintenance?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/alexey-lukin-memory-maintenance)More formats (shields.io, HTML) on the badges page.
---
name: memory-maintenance
description: "Use 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?\""
---
# Memory Maintenance
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_item_cementation_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`.
<!-- MEMORY-TRAPS-INDEX:AUTO — generated from traps.md by `ruby scripts/guard_craft_index.rb --write`; edit rules THERE, never here -->
1. Scout counts run LOW — and the direction is set by WHAT is counted, not by who counts
2. A «half-home» may be a duplicate — compare the two texts before believing they are coverage
3. One-way strings fake homelessness — a home that CITES you is a home you already have
4. Machine dedup is capped at VERBATIM, and on a bilingual corpus the gap is an order of magnitude
5. Declare the UNIT first — «debt weight» and «what an excision returns» differ in the SIGN
6. Mechanism ⊥ frame — «does this have a home» is TWO questions, and the homeless one is almost always the FRAME
7. An excision that TRANSLATES pays the bytes back — and looks like honest work while doing it
8. Measure the RECEIVER's headroom, not just the source's debt
9. «All three surfaces» is FOUR — the index is one of them
10. Ask whether the clause has TWO homes, not whether it has one
11. A `⊥` mark blesses the DIVERGENCE, not the missing router — it does not exempt a clause from phase 2
12. The claims that rot are almost exclusively SELF-LOCATION claims — and no sweep of the file that carries them can see it
13. The verdict ADDRESS-vs-SCOPE is decided by the source's GENRE, so read the genre before you read the pair
14. 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
15. A `TO-GIT` verdict needs THREE measurements, and the third is the one that manufactures work when skipped: does git ALREADY SEND readers to the memory copy
16. A restatement that SENDS can still LIE — so the redundancy question has a second axis, and only the second one is dangerous
17. 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
18. Editing memory through `Bash` bypasses BOTH of its carriers silently — the growth gate and the auto-commit are hooked on `Edit|Write`, and nothing announces their absence
19. Дзеркало пастки (18): авто-коміт робить ВАКУУМНИМ будь-яке порівняння «до/після», побудоване на робочому дереві — і брехня тут іде в бік «це не я»
<!-- /MEMORY-TRAPS-INDEX -->
## 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.
```
## Gotchas (hard-won, 2026-06-13)
- **Edit can't match a ~7000-char index line** → use a Ruby `lines[i] = …` replace with an `abort unless lines[i].include?("marker")` guard. 🔴 **For a multi-row pass the shape is a replacement TABLE, not a run of edits: every `old` must exist, so a typo MISSES safely instead of corrupting.** A substitution that silently matches nothing is the failure you want; one that matches the wrong span is the one you cannot see afterwards — which is also why the anchor must be UNIQUE, verified by counting it first, never a shared token. Then review the FULL diff rather than the changed rows: what survives this discipline is prose-mangling inside a row you did rewrite. ⚠️ The safety half is git now, not a `cp` backup (see the versioning gotcha below) — but versioning replaces the RECOVERY, never the review: a commit records the bytes, it does not notice that a sentence lost its verb.
- 🔴 **Zero-loss is a contract with a HARD set and a DECLARATION duty — and versioning repeals neither.** Hard, never thinned however routine they look: `[[strings]]` · guards and ⛔ stop-lists · open items · unique lessons · safety notes. Routine ID-examples and repeated instances may be thinned when their home is reachable — but **say what you removed**, because an honest report names the cuts, not only the keeps. Silence is the whole failure mode here: a thinned file reads exactly like a tidier version of the same file, so an undeclared cut is invisible at review time and stays invisible afterwards. ⚠️ The proof step used to be a set-diff against a `cp` backup; the corpus is versioned now, so it is `git diff` and `git show HEAD:<file>` — but the obligation did not move, it sharpened: git gives you recovery of a loss somebody NOTICED, and the declaration is the only thing that makes one noticeable.
- 🔴 **The corpus IS versioned now, and that repeals the premise most of this file was written under** (2026-08-08). `git init` at the memory dir, `main`, **local-only forever** — no remote, guarded by a `pre-push` hook that refuses, because two files carry the owner's personal circumstances and git history is permanent. Every write **made through Edit/Write** is committed automatically by `.claude/hooks/memory_git_commit.sh` (PostToolUse, subject `mem(<file>): <tool>`, body `session <id>` — so `git log -S '<phrase>'` now answers *"when did this claim enter and which session wrote it"*, which trap (12) used to answer by hand-grepping `*.jsonl`). **What this changes: irreversibility no longer sets the proof bar here.** The MIGRATE-FIRST prologue, the "two agents with OPPOSED frames before any excision" rule of trap (13a), and "preserve beats cleanup" were all priced against *unrecoverable* loss — under versioning the correct policy inverts from «when in doubt, keep» to **«when in doubt, cut and record the commit»**, which is also the only lever that ever pushed back on the growth `--weight` measures (DOC-T.62). ⚠️ **Two halves it does NOT repeal.** (a) *Reversibility is not correctness* — a wrong home is still wrong, and revert only helps a loss somebody NOTICES; the detectors that catch unnoticed loss (`corpus_floor_check`, `--audit`) carry that half and stay. (b) *CI still cannot see this corpus* — the gate remains the only enforcement point, and it fires at the write. 🔴 **(c) And the auto-commit has a hole shaped exactly like BULK curation, measured 2026-08-15: the hook rides `PostToolUse` on Edit/Write, so a batch applied through `ruby -e` in Bash — the very form this file prescribes for a long line or a replacement TABLE — writes the files and commits NOTHING.** Eight files sat uncommitted through a whole session and surfaced only on a closing `git status`. Note the shape: the heavier and more careful the pass, the more likely it evades the safety net, because the prescribed tool for a careful pass is the one the hook cannot see. **Reflex: any memory edit not made with Edit/Write ends with a manual `git -C <memory> add -A && commit` — and a closing sweep asks `git status` in the memory repo, not only in the repo.**
- 🔴 **The index ratchet is BYTE-wise, so an over-long hook is paid for in a haggling loop — write the hook short on the FIRST pass.** Measured 2026-08-09: adding one clause to an existing index line put `MEMORY.md` 146 B over its ratchet, and bringing it back cost **six** successive rewrites (146 → 105 → 50 → 39 → 13 → 3 → under), each a full edit-and-recheck cycle. Nothing was wrong with the gate — it did exactly its job — but the cost lands on the wrong side: the trimming happens *after* the thought is already phrased, when every remaining word feels load-bearing. Two consequences. (a) When a fact needs a new hook clause, draft it at roughly the length of the clause it sits beside, not at the length the idea wants. (b) Do not spend a second pass shaving a hook toward the ratchet — the policy says a new entry earns its line **by displacing one**, so at the second failed attempt the honest move is to look for the entry to evict (or to keep the detail in-file and shorten the hook to its trigger), never to keep golfing bytes.
- 🔴 **Сиблінг ратчета вище, і його бракувало: коли переповнюється сам ФАЙЛ (не індекс), лікуй у ПОРЯДКУ ЦІНИ, а не тим важелем, що першим спав на думку.** Найдешевший першим: **(1)** секція, що належить ІНШОМУ файлу **за ПОДІЄЮ** — безкоштовно, вона ніколи не була цього файлу; **(2)** евікція ТІЛ у наявний журнал-близнюк, правила лишаються на місці; **(3)** розкол клаузи, чиї половини належать двом РІЗНИМ подіям; **(4)** і лише тоді новий журнал. ⚠️ **(1) перевіряють ОБОВʼЯЗКОВО перед (2)** — «два вердикти про перенос» майже завжди є одним вердиктом, повтореним двічі. 📏 Прозова дієта на файлі біля стелі дає ~2%, тобто вона не важіль. 🔴 **Виміряно на собі 2026-09-06:** над стелею я зробив (2) наполовину, тоді **чотири рази поспіль гриз байти** — рівно те, що ратчет-урок вище забороняє, — і зрештою зняв власну клаузу; **важіль (1) не перевірявся ЖОДНОГО разу**. Ціна помилки не в байтах: golfing коштує повного циклу edit-and-recheck на кожен захід, а (1) коштує одного грепа по подіях.
- **Verify-before-delete** ([[feedback_verify_canon_before_delete]]) and **no-volatile-counts** ([[feedback_no_volatile_counts]]) apply to memory too (a hook must not hold drift-prone counts; trimmed detail must already live in the file).
- **De-dup is rare** — memories cross-link via `[[<slug>]]`, not restate; the big duplication is usually index-vs-file. Two distinct facts of the same kind are NOT a duplicate.
- 🔴 **«Merge + dedup» is NOT «shorten» — the founder stopped a pass mid-merge to say exactly that.** Collapsing N blocks keeps each block's CONTENT *verbatim*; what collapses is the STRUCTURE (N headers → 1 + tags) plus genuine duplicates (a recurring lesson → one shared note + a `→` pointer). **Compression is a SEPARATE operation and needs its own instruction** — a merge that quietly shortens is how a merge becomes amnesia, and the loss is invisible precisely because the result reads like a tidier version of the same thing. It lives here rather than in the housekeeping prompt because it fires at the MOMENT of the merge, and nothing routes a merger into that prompt.
- **`node_type` / `originSessionId` in the frontmatter are HARNESS-managed — do not strip them, and do not count them as yours.** A file-watcher re-stamps them on ANY write to `memory/*.md` (a Bash-only edit no longer evades it), so deleting them is wasted effort rather than damage; the direction that matters is the other one — never "clean" them out of a rewritten file expecting the change to stick, and never read their value as something this corpus decided. `format_check_one` in the gate checks `name` + `type` presence AND that `name:` equals the filename slug (the `NAME` verdict) — but nothing enforces the harness-managed pair, so that half stands. ⚠️ This sentence read «requires only `name` + `type`» for two weeks: the slug axis landed **75 minutes after** the claim was written, in the gate rather than here — a self-location claim is falsified by an edit in ANOTHER file, which is why it reads fresher the longer it stands.
- 🔴 **Step 6A's own instrument lies by default: the corpus routes to the tracker by BARE ID, not by the literal `00_07`.** Measured 2026-08-06 — a scan for "memories carrying open-action markers with no `00_07` reference" returned four files, and **all four were false positives**: they route via `ARCH.78` · `HW.39` · `SEC.21`, which is the corpus's actual convention and a better one (an ID survives the tracker being renamed or re-sectioned). So the step-6A predicate is *"does an open item name a LIVE tracker ID"*, never *"does the file contain the string `00_07`"* — and the verification is two-step: extract the IDs, then check each against the tracker's live-vs-`§🗄️` split. ⚠️ The mirror bites on the second step too: an ID-extraction regex anchored on `^#### ID` headings and `| ID |` archive rows called **13 of 16** IDs "absent from the tracker" when they were merely referenced inline — an **81 % false-positive rate**, cured by one direct `grep -rl` per candidate. **Both halves of this check are instruments; price them before believing either.** 🔴 **And the predicate is still too weak by one question: «is the ID LIVE» does not ask «is it the RIGHT ID»** (2026-08-07). Two memory routers sent a class's state to a tracker item that was archived — and the archived item had never been about that class at all: `git show` of the commit that created it showed a different subject from birth. Nothing catches this, and the reason is worth carrying: `code_tracker_id_check` asks only whether a cited ID *has a home*, so a wrong-but-existing address passes it forever, exactly like a resolving `[[link]]` pointing at the wrong file in trap (6). The tell is cheap when you look for it — **grep the tracker for the class's own distinctive token** (here a landed byte-count) and see which `####` item actually carries it; that item is the address. Fix it in place, never annotate it, and prefer routing to the item that carries the NUMBER over the item whose title sounds related. And when a genuine ghost does surface, read it before calling it decay — all three survivors that day were **deliberate tombstones in three distinct shapes: an ID *merged* into another, an ID *renamed*, and an ID struck through beside its own deletion date** — i.e. exactly the records that make a dropped ID recoverable, and never decay. ⚠️ **The shapes are the lesson; the dead IDs themselves are deliberately NOT quoted here, and that is enforced, not stylistic** — `scripts/code_tracker_id_check.rb` scans `.claude/**` and cannot distinguish an illustrative citation from a live one, so writing a retired ID into a skill turns it into a phantom reference and reds the gate. (Learned by doing it: the very paragraph documenting that ghost IDs are legitimate created three of them.) Need the evidence? It lives in the memory files that carry those tombstones — read it there, where a dead ID is the point rather than a citation.
- **«This file has no line in `MEMORY.md`» is NOT a finding for a `log_*` journal — it is the design.** Measured 2026-08-05: **zero of ten** journals carry an index line; they are reached by `[[strings]]` alone (2–15 inbound each), which is exactly the demotion the index-vs-strings measurement prescribed. An agent that flags it as a risk is reporting the norm, so check the population before acting — the real question for a journal is whether its inbound count is healthy, not whether the index names it. 🔴 **Corollary that decides whether the split SURVIVES: create a rule-home's `log_*` twin BEFORE you need it.** The gate's whole strategy is to redirect the cheap end-of-session `append` into the journal instead of fighting it — but if the journal does not exist yet, the redirect costs a file creation, a routing decision and an index question at the exact moment the author wanted one line, and that friction is what produced every one of the four recorded rollbacks. A twin that already exists turns the prescribed move back into an `append`.
- **The prompt's own §Durable-уроки = a 6-family frame (auto-consolidate — the method applies to itself):** a new lesson gets **melted into the fitting family as a line**, NOT glued on as a fresh date-stamped paragraph (the section already bloated into a wall once and had to be refactored). New family only if it fits none (keep ≤~7); a family past ~6 lines → compress that family the same way.
> If you're tempted to add the memory FORMAT rules or live state here, stop — format → system prompt; state → the memories; the full method → `.claude/prompts/memory_housekeeping.md`. Keep this skill a thin pointer.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!