bug(obsidian): obsidian-export leaves stale notes for hard-deleted and renamed observations
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 62/100
Direzione di ricerca
Start in internal/obsidian/exporter.go: the cleanup loop only visits rows from store.Export() with DeletedAt set, and the export loop overwrites state.Files[obs.ID] without comparing the old path. Reproduce with the numbered steps (hard delete, then a PATCH rename, then export) and check .engram-sync-state.json. Done when hard-deleted and renamed notes are removed or moved, orphaned hubs are pruned, and the export output reports the deletions.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Existing Issue Search
- I searched existing issues and will add evidence to a canonical tracker when applicable.
📝 Observed Consequence
engram obsidian-export leaves Markdown notes in the vault that no longer correspond to any live observation, and keeps reporting Deleted: 0. Two triggers:
- Hard-deleted observations (
engram delete <id> --hard,engram delete project <name> --hard, or any hard deletion that happens between two exports): the note, and its session hub, stay in the vault forever. Their entry also stays in.engram-sync-state.json. - Renamed observations (title updated, so the slug changes): the next export writes a new file and overwrites the state entry with the new path. The old file stays on disk and is no longer tracked by the state, so not even a state-based cleanup can find it.
Soft deletion works correctly: engram delete <id> followed by an export removes the note (Deleted: 1).
On a real vault, after a bulk hard deletion and normal use, this accumulated several hundred stale notes plus orphan session and topic hubs, all shown in Obsidian search and Graph View as if they were live memories.
🔄 Steps to Reproduce
- Isolated store and vault:
T=$(mktemp -d); e() { HOME="$T/home" ENGRAM_DATA_DIR="$T/data" engram "$@"; } e save "keep me" "first body" --project demoande save "hard gone" "second body" --project demoe obsidian-export --vault "$T/vault" --all --graph-config skip→Created: 2e delete 2 --harde obsidian-export --vault "$T/vault" --all --graph-config skip→Deleted: 0;engram/demo/manual/hard-gone-2.mdstill exists and.engram-sync-state.jsonstill maps"2"to it.- Rename observation 1 through the HTTP API:
e serve 17499 &, thencurl -X PATCH 'localhost:17499/observations/1?expected_project=demo' -H 'content-type: application/json' -d '{"title":"keep me renamed"}', then stop the server. e obsidian-export --vault "$T/vault" --all --graph-config skip→Created: 1, Deleted: 0; bothkeep-me-1.mdandkeep-me-renamed-1.mdexist, and the state only knowskeep-me-renamed-1.md.
✅ Expected Behavior
After an export, the vault contains exactly one note per live observation:
- Notes tracked in the state whose observation no longer exists in the store at all (hard-deleted) are removed, like soft-deleted ones.
- When an observation's target path changes, the previously tracked file is removed (or moved) before the state entry is overwritten.
- Session/topic hubs that no longer reference any live observation are removed.
❌ Actual Behavior
# after hard delete of #2
Obsidian export complete
Created: 0
Updated: 0
Deleted: 0
Skipped: 1
Hubs: 1
engram/demo/manual/hard-gone-2.md <- still present
engram/demo/manual/keep-me-1.md
# after renaming #1
Created: 1
Updated: 0
Deleted: 0
engram/demo/manual/keep-me-renamed-1.md
engram/demo/manual/keep-me-1.md <- stale, untracked
engram/demo/manual/hard-gone-2.md <- still present
Operating System
macOS
Release Version (Report Context)
3.4.0
Agent / Client
Other
📋 Relevant Logs
No response
💡 Additional Context
Client: Pi (via gentle-engram); the exporter is client-independent.
Current main (8589a5f), internal/obsidian/exporter.go:
- The cleanup loop only visits rows returned by
store.Export()that haveDeletedAt != nil. Hard-deleted rows are not returned, so theirstate.Filesentries are never reconciled. - The export loop computes
relPathfrom the current slug and assignsstate.Files[obs.ID] = relPathwithout comparing it with the previously tracked path.
A possible approach: after the export loop, remove every tracked state.Files entry whose ID is not a live observation, and when the tracked path for a live ID differs from the new relPath, delete the old file (with the same containment checks used today).
Workaround: compare the state's file IDs with live observation IDs, then delete the orphaned files and prune the state by hand, after taking a backup.
- Lingua principale
- Go
- Stelle
- 7.1k
- Fork
- 729
- Merge medio
- 10h 43m
- PR unite (30g)
- 332
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Gentleman-Programming/engram
-
status:needs-review type:bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Gentleman-Programming/engram#1687 ·
I maintainer di solito rispondono entro 1 giorno
-
priority:medium status:needs-review type:feature
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
Gentleman-Programming/engram#863 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
question(sync): isolate enrolled-repair writer blocking in a reproducible fixtureForse già presa @dnlrsls l’ha presa oggi. Apertastatus:approved type:question
Gentleman-Programming/engram#1913 · 3 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 1 giorno
-
status:needs-review type:bug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 12/100
Gentleman-Programming/engram#1912 ·
I maintainer di solito rispondono entro 1 giorno
-
status:needs-review type:bug
Difficoltà 5/5 Più di una settimana Idoneità per principianti 15/100
Gentleman-Programming/engram#1911 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Gentleman-Programming/engram
Issue simili
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:session-state issue-rating: 🦞 diamond lobster no-stale P2
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
openclaw/wacli#503 · 1 commento · 1 reazione ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 81/100
apache/rocketmq-dashboard#6895 ·
I maintainer di solito rispondono entro 3 giorni
-
agent-butler-finding chore
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100
jordansmall/spindrift#5466 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 92/100
open-telemetry/opentelemetry-go-compile-instrumentation#1507 ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 87/100
777genius/agent-notifications#490 ·
I maintainer di solito rispondono entro 1 giorno