From 5d6e9e7e1c624fe22dbe716b82d1d00bae35d9df Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 02:46:30 +0000 Subject: [PATCH 1/3] memory-cleanup: a server it cannot read holds the night open Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013jkdGEbQZnXUy1kATtYcQ6 --- docs/SONNY.md | 5 ++++- sonny/skills/memory-cleanup/SKILL.md | 10 +++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/SONNY.md b/docs/SONNY.md index b854f00c2..607a8234b 100644 --- a/docs/SONNY.md +++ b/docs/SONNY.md @@ -429,7 +429,10 @@ so a later lead names the pattern rather than the instance, and removes it when their words show it stopped. It also saves how they took what an agent did unasked, which is how far leads go on their own. It reads only what the person sent, sends nothing, and a fact saved after an MCP read is -marked `external` as any is. +marked `external` as any is. A server it cannot read, as one whose sign-in +expired, gets an `unreadable-SERVER` fact, and that night is left +unfinished, so the next one reads from the same time and catches up; after +three days it finishes without it. `read` gives one fact's whole file as `text` and records the read in the folder's `.reads` (`{NAME: {last, count}}`), which is neither a fact nor diff --git a/sonny/skills/memory-cleanup/SKILL.md b/sonny/skills/memory-cleanup/SKILL.md index da1b209e0..530490b14 100644 --- a/sonny/skills/memory-cleanup/SKILL.md +++ b/sonny/skills/memory-cleanup/SKILL.md @@ -91,12 +91,20 @@ of it ends `tool_unserved`, run the same command with sent, not what others sent them, and save nothing about other people. Read only: send, reply, mark or move nothing there. A fact saved after reading them is marked `external`, as any is; keep it. + - When a server you meant to read fails, as when its sign-in expired, + save or update a `reference` fact named `unreadable-SERVER` with the + error and since when, and remove it the night that server reads + again. Then skip step 6 tonight, unless `since_ms` is more than three + days old: memory stays as you leave it, and the next night starts + from the same `since_ms` and reads what was missed. Habits keep their + dates, so a night read twice counts nothing twice. 6. Call it with `cleanup` `finish`. It commits the cleanup, or refuses with `loss_guard` and puts memory back when the cleanup removed more than a quarter of the facts (two at least). A refusal means you removed too much: do not try again tonight. 7. Reply with one line per change: what you saved, merged, removed or - re-dated, and why. Reply `No changes.` when there were none. + re-dated, and why, and a line for each server you could not read. + Reply `No changes.` when there were none. ## Do not From 2f35347db655efdff3b53a67ee9c4dd98a6bc14e Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 02:46:41 +0000 Subject: [PATCH 2/3] FEATURES: #411 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013jkdGEbQZnXUy1kATtYcQ6 --- sonny/FEATURES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonny/FEATURES.md b/sonny/FEATURES.md index d7cef0e53..2b41a7de9 100644 --- a/sonny/FEATURES.md +++ b/sonny/FEATURES.md @@ -95,7 +95,7 @@ per feature; group small things into the row they belong to. |---|---|---|---|---| | `ask`: a question for the person, as a decision card with reasons | shipped | pinned questions above the composer 10-27 #192; declared tool 10-27 #225; decision card where it was asked 10-28 #245; options are buttons 10-29 #326 | Agents ask instead of guessing; the person answers in one click | ? | | `plan`: the agent's plan, drawn in the conversation | shipped | added 10-27 #225 | See the steps an agent intends | ? | -| Memory (`sonny memory`, the memory skills, nightly cleanup) | shipped | app memory 10-09 #82, 10-10 #104, #120; moved into Sonny 10-27 #189; a tool 10-28 #278; 16 KiB 10-28 #241; read tracking, 30-day unread check 10-29 #354; outside-content marks 10-29 #356; the cleanup reflects on habits, from the person's words and what they sent through their servers 10-30 #403 | Later agents start knowing what earlier ones learned | ? | +| Memory (`sonny memory`, the memory skills, nightly cleanup) | shipped | app memory 10-09 #82, 10-10 #104, #120; moved into Sonny 10-27 #189; a tool 10-28 #278; 16 KiB 10-28 #241; read tracking, 30-day unread check 10-29 #354; outside-content marks 10-29 #356; the cleanup reflects on habits, from the person's words and what they sent through their servers 10-30 #403; a server it cannot read holds the night open 10-30 #411 | Later agents start knowing what earlier ones learned | ? | | Triggers (`sonny trigger`): wake an agent at a time, on a file, a commit, or by name | shipped | app triggers 10-10 #89-#92; moved into Sonny 10-27 #189; skipped checks, `--replace` 10-28 #241; a tool 10-28 #278; Linux via systemd 10-29 #344; `--start` agents get Sonny's tools 10-30 #403 | Work that starts while nobody is at the terminal | ? | | Turn-end triggers | removed | added 10-10 #89-#92; removed 10-27 #189 | Leads hear of task turns from task updates and the lookout | ? | | Goals: keep an agent working until a check command passes | experimental | added 10-29 #341; `/goal WHAT` asks the agent to set one, `/goal` shows, `/goal clear` clears 10-30 #397 | Autonomy with a check, not a model's say-so | ? | From abb827ca268d4e736f50f88ea0c89969d46a7423 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 30 Oct 2026 02:48:49 +0000 Subject: [PATCH 3/3] memory-cleanup: the first night finishes without an unreadable server Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_013jkdGEbQZnXUy1kATtYcQ6 --- docs/SONNY.md | 4 ++-- sonny/skills/memory-cleanup/SKILL.md | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/SONNY.md b/docs/SONNY.md index 607a8234b..b4bdce762 100644 --- a/docs/SONNY.md +++ b/docs/SONNY.md @@ -431,8 +431,8 @@ agent did unasked, which is how far leads go on their own. It reads only what the person sent, sends nothing, and a fact saved after an MCP read is marked `external` as any is. A server it cannot read, as one whose sign-in expired, gets an `unreadable-SERVER` fact, and that night is left -unfinished, so the next one reads from the same time and catches up; after -three days it finishes without it. +unfinished, so the next one reads from the same time and catches up; the first night, and after +three days, it finishes without it. `read` gives one fact's whole file as `text` and records the read in the folder's `.reads` (`{NAME: {last, count}}`), which is neither a fact nor diff --git a/sonny/skills/memory-cleanup/SKILL.md b/sonny/skills/memory-cleanup/SKILL.md index 530490b14..f22171a06 100644 --- a/sonny/skills/memory-cleanup/SKILL.md +++ b/sonny/skills/memory-cleanup/SKILL.md @@ -94,8 +94,9 @@ of it ends `tool_unserved`, run the same command with - When a server you meant to read fails, as when its sign-in expired, save or update a `reference` fact named `unreadable-SERVER` with the error and since when, and remove it the night that server reads - again. Then skip step 6 tonight, unless `since_ms` is more than three - days old: memory stays as you leave it, and the next night starts + again. Then skip step 6 tonight, unless `since_ms` is null (the first + cleanup, which has no earlier night to read again) or more than + three days old: memory stays as you leave it, and the next night starts from the same `since_ms` and reads what was missed. Habits keep their dates, so a night read twice counts nothing twice. 6. Call it with `cleanup` `finish`. It commits the cleanup, or