Skip to content

fix: make IdeaLoom list deletion actually delete, and pin its federation boundary - #5364

Merged
atomantic merged 2 commits into
mainfrom
claim/issue-5361
Aug 29, 2026
Merged

fix: make IdeaLoom list deletion actually delete, and pin its federation boundary#5364
atomantic merged 2 commits into
mainfrom
claim/issue-5361

Conversation

@atomantic

Copy link
Copy Markdown
Owner

Summary

  • Fixes a real bug: DELETE /api/brain/ideas/idealoom/lists/:id answered 404 for every list, so the Brain IdeaLoom UI could never delete one — it toasted "Failed to delete IdeaLoom list" and left the row in place. deleteList returned store.deleteOne(id), which resolves to undefined whether or not the record existed. It now probes for the record inside the same per-id write queue as the removal and returns a real boolean.

  • Adds the CRUD coverage Add machine-local IdeaLoom list storage and validated local API #5336 implied but never wrote — read-by-id, delete, the idempotent second delete, the malformed-id guards on all three id-addressed operations, and both 404 shapes at the route. That gap is exactly why the delete bug shipped.

  • Adds server/services/idealoomLists.boundary.test.js, the missing proof that no IdeaLoom list payload or vault sync metadata crosses the Brain federation seam (ADR docs/decisions/2026-08-08-privacy-records-machine-local.md). It drives the real modules over a temp data root rather than asserting on mock calls:

    • the reconcile snapshot carries a native Brain idea but none of the list's id/prompt/note path;
    • getBrainChecksum() is byte-identical across list create/update/settings writes, with a forced cache invalidation plus a native-write bypass probe so it cannot pass vacuously;
    • brainSync.applyRemoteChanges and brainReconcile.applyBrainSnapshot both refuse an idealoom-lists payload and write nothing to the store;
    • the memory bridge has no mapping for the type, so brainRecordToMemory cannot bridge a list.

    Today those guarantees hold only structurally — nothing fails if a later slice registers an IdeaLoom type in BRAIN_ENTITY_TYPES or the bridge's TYPE_MAP. Add explicit opt-in IdeaLoom Obsidian import and export #5338/Make IdeaLoom Obsidian sync conflict-safe and document its contract #5339 are about to hang vault paths and note content hashes off these records, so the boundary needed a test rather than a comment.

Unrelated fix rolled in

The first commit regenerates server/lib/apiRouteCatalog.generated.json. b9893531c added image-generation routes without re-running npm run generate:api-docs, so scripts/generate-api-route-catalog.test.js has been failing on main since — it would have reddened this PR's CI. Regenerated by the script; no hand edits.

Test plan

  • cd server && npx vitest run services/idealoomLists.test.js services/idealoomLists.boundary.test.js routes/brain.test.js — 125 passed.
  • Bug confirmed: reverting only the deleteList change fails the new deletes a list and reports whether anything was removed test with expected undefined to be true.
  • Non-vacuity confirmed: each federation-refusal test seeds a real list first and asserts a non-empty store before the refusal, and each passes when run in isolation.
  • cd server && npm test — full suite green (the two pre-existing route-catalog failures are resolved by the first commit).

Closes #5361

b989353 added image-generation routes without re-running
`npm run generate:api-docs`, so the generated catalog no longer covered
them and generate-api-route-catalog.test.js has been failing on main since.
Regenerated; no hand edits.
…ion boundary (#5361)

`deleteList` returned `store.deleteOne(id)`, which resolves to `undefined`
whether or not a record existed. The route reads that as "not found", so
`DELETE /api/brain/ideas/idealoom/lists/:id` answered 404 for every list and
the Brain IdeaLoom UI could never delete one — it just toasted "Failed to
delete IdeaLoom list" and left the row in place. `deleteList` now probes for
the record inside the same per-id write queue as the removal and returns a
real boolean.

The bug survived because the CRUD coverage #5336 implied was never written.
This adds it: read-by-id, delete, the idempotent second delete, the malformed-id
guards on all three id-addressed operations, and both 404 shapes at the route.

Also adds `idealoomLists.boundary.test.js`, the missing proof that no list
payload or vault sync metadata crosses the Brain federation seam. It drives the
real modules over a temp data root and asserts the reconcile snapshot carries a
native Brain idea but none of the list's id/prompt/note path, that the reconcile
checksum is byte-identical across list writes (with a native-write bypass probe
so the assertion cannot pass vacuously), that `brainSync.applyRemoteChanges` and
`applyBrainSnapshot` both refuse an `idealoom-lists` payload without writing to
the store, and that the memory bridge has no mapping for the type. Today those
hold only structurally; #5338/#5339 are about to hang vault paths and note
hashes off these records, so the guarantee needed a test rather than a comment.

Closes #5361
@atomantic
atomantic merged commit b5cf332 into main Aug 29, 2026
7 checks passed
@atomantic
atomantic deleted the claim/issue-5361 branch August 29, 2026 02:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a federation-boundary test and full CRUD coverage for the machine-local IdeaLoom list store

1 participant