Files
nanobot-runtime/skills/compact-memory/SKILL.md
2026-08-27 14:18:51 +02:00

7.5 KiB
Raw Blame History

name, description
name description
compact-memory Audit and compact memory/MEMORY.md by removing superseded, duplicated, overly detailed, or ephemeral entries, and merging related items within a subsection. Runs interactively when the user asks; nightly mode is driven by a script.

compact-memory

Compact memory/MEMORY.md when it grows too large or stale. The skill reads memory/MEMORY.md plus USER.md, SOUL.md, and keep.md (all three in the workspace root) to detect duplicates and outdated context, but only ever changes memory/MEMORY.md.

When to use

  • User says "compact memory", "clean up MEMORY.md", "memory audit", or similar.
  • MEMORY.md exceeds ~250 lines.
  • There are obvious duplicates between MEMORY.md and other memory files.
  • Old project notes, ephemeral debugging details, or superseded facts accumulate.

The line threshold is only a proactive trigger. When the user invokes the skill explicitly, run the full audit regardless of line count.

Modes

Interactive mode (default)

You perform every step yourself with your file tools. There is nothing to exec or spawn.

  1. Read memory/MEMORY.md, and — for duplicate detection — also USER.md, SOUL.md, and keep.md (all three in the workspace root).
  2. Count total lines (wc -l memory/MEMORY.md). If the skill was not invoked explicitly by the user, the file is ≤ 250 lines, and there is no obvious staleness, report "nothing to clean up" and stop. When invoked explicitly, always continue to the audit.
  3. Audit the WHOLE file in a single pass. Walk every ## section and every ### subsection in order, top to bottom, and evaluate every bullet. Do not stop after the first few findings — the proposal in step 5 must cover the entire file at once. Re-running the skill should find nothing left, not "the next batch".
  4. Identify candidates:
    • superseded — replaced by newer facts, completed work, or no longer relevant.
    • detail — concrete commands, flags, paths, measurements, or code references (e.g. telegram.py:384, script paths, DB paths) that belong in a skill, in code, or in a results/ file.
    • duplicate — same fact already present in USER.md, SOUL.md, or keep.md.
    • ephemeral — one-off debugging, temporary state, resolved incidents, or transient build/run progress (counts, task-failure notes, in-flight status).
    • stale section — an entire ##/### section whose contents are all superseded or ephemeral (e.g. a finished project, a one-off task log, transient system state). Propose removing the whole block at once, not bullet by bullet.
  5. Identify merge candidates within the same ### subsection — related bullets that can be combined into one concise bullet.
  6. Present a single numbered proposal in chat that covers the entire file:
    • list each delete with reason and original text (use [stale section] and cite the heading for whole-section removals);
    • list each merge with merged text.
    • Kept items are not listed.
  7. Wait for user approval. Accept commands like:
    • apply / ok / yes — apply all proposed changes.
    • keep 3, 7, 12 — keep listed items, apply the rest.
    • delete 2, 5 — delete only listed items.
    • cancel — abort.
  8. Apply approved changes to memory/MEMORY.md.
  9. Append deleted items to log/memory-clean.log with timestamp YYYY-MM-DD HH:MM, one line per item, via exec shell append so existing lines cannot be lost: printf '%s\n' '<YYYY-MM-DD HH:MM> DELETED [<category>] "<text>" — <reason>' >> log/memory-clean.log
  10. Report summary.

Nightly mode (script-driven)

Triggered only by scripts/compact_memory_auto.py from the crontab. Never start this mode from a chat message — the change-set you produce here is applied by the script, and outside that script nothing would apply it. A user asking for an unattended-style cleanup in chat gets interactive mode.

You change nothing in this mode. Do not edit memory/MEMORY.md, do not write a backup, do not touch log/memory-clean.log. The script applies the change-set, writes the backup and the log, and composes the message the user receives. Your prose is never delivered.

  1. Run the same audit as interactive mode steps 15.
  2. Answer with exactly one ```json code block and nothing else — no narration, no summary, no text before or after it.
  3. Nothing qualifies → a block with an empty changes list.
  4. If the script replies that the validator rejected your change-set, fix exactly what it lists and answer again with one corrected block and nothing else.

When in doubt, keep the item — no user is there to prune, and there is no way to mention what you kept.

Output format

Interactive proposal

Found X candidates to change in MEMORY.md:

Delete:
1. [superseded] <text>
2. [detail] <text>
3. [stale section] ## <heading> (N bullets) — <reason>
...

Merge:
5 + 6: <merged text>
...

Commands: apply | keep <numbers> | delete <numbers> | cancel

Nightly change-set

{
  "changes": [
    {
      "op": "delete",
      "category": "ephemeral",
      "original": ["- Debug run 2026-07-25: output-format test in progress"],
      "reason": "one-off debug marker, task finished"
    },
    {
      "op": "merge",
      "original": [
        "- Runs as a systemd user service `nanobot.service`",
        "- Model switching via `my` tool requires `tools.my.allow_set = true`"
      ],
      "new_text": ["- Runs as a systemd user service `nanobot.service`; model switching via `my` needs `tools.my.allow_set = true`"],
      "reason": "same subsection, one topic"
    }
  ]
}

Nothing to change:

{
  "changes": []
}

Field rules — the validator rejects the whole change-set if any of these is violated:

  • op"delete" or "merge". No other fields than the ones shown above are allowed.
  • categorydelete only, one of superseded, detail, duplicate, ephemeral, stale-section.
  • original — list of whole lines copied character-for-character from MEMORY.md, in file order, max 20 lines. The block must appear in the file exactly once, so include enough surrounding lines to make it unique.
  • new_textmerge only, list of lines replacing original. Max 3 lines, max 300 characters, and always fewer lines than original.
  • reason — max 120 characters, in English, one clause saying why. It is shown to the user verbatim.
  • Blocks of different items must not overlap, and the change-set must not remove more than half of the file.

Rules

  • Only ever change memory/MEMORY.md — and in nightly mode not even that; the script does it.
  • Do not touch SOUL.md, USER.md, or keep.md.
  • In interactive mode do not create backups of MEMORY.md; rely on log/memory-clean.log for traceability.
  • log/memory-clean.log is append-only: write new lines with >> via exec, never with write_file/edit_file. Never delete, reformat, or "clean up" existing lines — not even ones that do not match the current format.
  • Write to log/memory-clean.log only when something was deleted or merged — never a "no changes" entry.
  • Merge only within the same ### subsection (never across ## sections or across different ### subsections).
  • Preserve active project context, user preferences, and durable infrastructure facts.
  • Be exhaustive: propose every qualifying candidate in one pass, not a handful. In interactive mode the user prunes via keep/delete, so propose generously and flag borderline items rather than silently keeping them.

Example

User: compact memory

Agent: reads files, counts lines, proposes changes, waits for apply.