Repository navigation
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: 1dcfee666d624428ae95d5d57a0e3185
Branch: dev/2-memory-blocked-empty
Base: 1778add
At: 2026-11-02T02:13:33Z
A memory folder that is refused reads as "this Bot has never saved anything" — the panel has no word for "I could not read it".
What happens today (live main 1778add0ace4, read not assumed)
core/src/host/memory.js:445— when a segment of the memory folder is not a plain directory,warnFolder()writes one host log line (ds-bot: memory folder is not a plain directory %s; keeping it empty) and the reader answers exactly what it answers for a missing folder.folderKind()(:462-474) already knows the difference and already knows the failing path: it answersreal/absent/other, withat= the segment that failed. Nothing on the read path carries that answer outward.memoryView()(:1166-1189) returnsbotId,entries,sizes,limits,summary,fresh,summarizing,error. There is no field that says a folder was refused, soentries: []is the only thing the client sees.core/src/client/memory-panel.js:69-72therefore renders{name} has not saved anything yetplus "Bots keep lasting preferences… Tell {name} below" for every empty view — including the one where the Bot did save things and the home cannot read them.
So a user is told to type something that cannot be saved, and a silent refusal is indistinguishable from a fresh Bot. #2068 / #2079 / #2083 / #2089 were all spent on this refusal path; the refusal itself works, only the report is missing.
Reproduction
- Home whose
memory/(ormemory/bots, or a scope folder under it) is a symlink to a directory outside the home. - Open the Memory panel for a Bot.
- Panel:
{name} has not saved anything yet. Host log: the onekeeping it emptywarning.memory-viewover the API:entries: [], nothing else says why.
Expected
memory-viewgainsblocked: one entry per scope that is refused —{ scope: 'own' | 'team', path }built from the existingfolderKind(...)result,path= itsat. Onlykind === 'other'is blocked;absentis a normal empty home and must stay out of it. Empty answer when nothing is refused.- The panel, when
entriesis empty andblockedis non-empty, renders one line above the existing empty title naming the path and saying the folder is not a plain directory so it cannot be read. With nothing blocked the copy is byte-identical to today. - Because the suite has no React renderer, the decision goes in an exported pure helper in the panel model (same shape as
bot-row-title/at-menu), tested directly.
Acceptance (red first)
- Host: linked
memory/→blockednames that scope and the failing path,entriesstill[]. Red today: the field does not exist. - Host: plain folder with no entries →
blockedempty (guards against a flag that is always on),entries[],freshunchanged. - Client: the helper answers the notice for a blocked view and
nullfor a plain empty view. Red today. core/test/i18n.test.jsalready fails anyt('…')literal without a Chinese entry — the new strings go intoDICTIONARY.zh(core/src/client/i18n.js).
Scope
core/src/host/memory.js, core/src/client/memory-panel.js, core/src/client/i18n.js, core/test/memory.test.js, one new client test file, docs/subsystems/core-host.md if the memory-view contract is documented there, one changelog.d/ fragment. Client and i18n files are mirrored into ds-bot/ through patches/ds-bot/ — npm run generate + scripts/ds-bot-patches.mjs canonical must stay no-op clean.
Not in scope
- Not changing the refusal itself, the entry/summary behaviour, permissions, or the once-per-folder warning.
- Not adding a "retry" or a repair path; the panel only says why it is empty.
- Not exposing host paths anywhere but this one line (the path is the home's own memory folder, which the panel already belongs to).
Dedup (checked before opening)
- Live main
1778add0ace4: the stringhas not saved anything yetexists only incore/+ds-bot/mirrors of the panel; noblockedfield on the view; no client helper for it. - Issues:
"has not saved anything yet"→ 0;memory panel empty→ 0;folderKind→#2071(closed, merged — it added the resolver and the refusal; this asks only to report the refusal);memory-view→ 34 hits, reviewed#2068/#1910/#1740/#1887, none about the empty state naming the refusal.
Activity
HugoXK commentedon Nov 2, 2026
Release
Written-by: FlyBot Lead
Released: 1dcfee666d624428ae95d5d57a0e3185
Reason: merged as c0a76ed via PR #2105 (merged_at 2026-11-02T02:53:05Z)
At: 2026-11-02T02:54:45Z