Library and trash
Why Delete asks nothing and Delete forever asks twice, what 90 days actually governs, and what a backup does and does not contain.
None of the shipped strings quoted here contains an em dash, so nothing is substituted; they are verbatim. In a quote, a name in braces, such as {name}, or a capital N stands for a part the app fills in as it runs. Three dots at the start or end of a quote stand for words left out, unless the article says the app prints them.
The 90 days, and why you can trust the number
Deleted items wait 90 days before they are purged for good. The number is
RETENTION.deletedGraceDays in packages/core/src/constants.ts:338. The web app imports it
everywhere it appears (apps/web/src/lib/library/model.ts, purge.ts). The desktop cannot import it
(no bundler), so it carries its own GRACE_DAYS = 90 (apps/desktop/src/board.js, search the identifier - the
line moves and this cite has been stale twice), and
scripts/check-promises.mjs fails the build if the two copies ever differ, and if the web ever
grows a second local copy (joined-to-code: scripts/check-promises.mjs).
Delete versus Delete forever
Delete asks no confirmation BECAUSE it is reversible for the whole grace period. Delete forever asks BECAUSE it is not: on the web, an inline details block reads "This removes the item and its stored file permanently. It cannot be undone." (apps/web/src/app/dashboard/asset-actions.tsx:157); on the desktop it is a counting confirm (joined-to-code: cleanup and trash harness checks).
Purging a live item on the web is refused server-side: "Delete it first - this only empties the
trash." (apps/web/src/lib/library/actions.ts, purgeAssetNow's refusal of a live item).
On the desktop, files are touched only at purge: delete never removes a recording file; purge removes card and file together or keeps both (joined-to-code: trash harness checks). The purge sweep runs once per launch, and a locked file keeps its card for the next launch rather than orphaning the file (joined-to-code: harness). A card you uploaded waits too: it leaves the Trash for good only once the server has answered that its copy is taken back or already gone, so it can stay past its 90 days, for example while Sharing is off. Delete forever keeps such a card as well and says "Nothing was deleted: {reason}" (apps/desktop/src/board.js); Delete selected forever and Delete shown forever keep it too and say how many were kept and why. Trash is sorted by deletion time, and the item count in the header counts live cards only (joined-to-code: harness).
Desktop delete shows the toast "Moved to Trash - restorable for 90 days" (apps/desktop/src/board.js, search the toast text - the line moves). There is no undo button in that toast today; that gap is already filed.
Share links die in the trash
In your library on the web, deleting a capture kills its share link immediately; restoring revives it. Pinned live by apps/web/e2e/library.spec.ts: the link answers 200, then 404 while trashed, then 200 after restore (joined-to-code). The web trashed-asset page says it in one banner: "This is in the Trash. {days left} - after {grace} days it and its stored file are removed for good. Its share link does not work while it is here." (apps/web/src/app/dashboard/a/[id]/page.tsx, the trashed branch's warn panel, where {grace} is 90; a construct, not a line, since 2026-10-16). On the desktop, deleting a card you uploaded asks the server to move its copy to your workspace's Trash, so its share link stops working. If that fails, for example because Sharing is off, the card still goes to the Trash here and the app says "Moved to Trash here, but the copy in your workspace is still there and its share link still works: {reason}" (apps/desktop/src/board.js). If the app is not signed in, sign in from Settings, then restore the card from the Trash and delete it again: that Delete asks the server once more. With Sharing on, signing in also uploads each recording you finish from then on. If you would rather not sign in, or Sharing is off, delete the copy in your library on the web. A walkthrough made from the recording is not taken back, and nor is a card uploaded by a version of the app before 0.17.0 (August 2026): remove those from your library on the web. Restoring the card on the desktop does not bring the copy back: restore it in your library on the web. In the browser extension, deleting a card does not take back a copy you uploaded from it, so that copy's share link keeps working: remove it from your library on the web if you want it gone. Cross-reference sharing.md.
Empty states are three different sentences on purpose
- Trash empty: the trash view's own empty message.
- Filter matched nothing: "No items match this filter." (apps/web/src/app/dashboard/(library)/page.tsx:437). Your work is hidden, not gone.
- Genuinely empty: "No captures yet." (apps/web/src/app/dashboard/(library)/page.tsx), then "Captures from the desktop app and the browser extension land here too." (apps/web/src/app/dashboard/(library)/page.tsx). Until 2026-08-26 that second sentence pointed only at the other two apps; the web app takes captures itself now. There is no button: for editors the capture panel already sits at the top of the same page, so the Take your first capture button that pointed at it was removed on 2026-09-20 (page.tsx records why, where the button stood). A viewer gets no panel, because every capture is a write.
A failed read is its own card, not an empty state: "Nothing has been deleted: this is a read failure, not an empty library." (apps/web/src/app/dashboard/(library)/page.tsx:407).
The web list shows 200 items a page (LIBRARY_LIMIT in apps/web/src/lib/library/model.ts) and
pages past that with Previous and Next links under the list (apps/web/src/app/dashboard/library-pager.tsx).
A library that fits on one page shows no pager at all. A page past the end, such as an old bookmark,
says "There is nothing on page {N}." (apps/web/src/app/dashboard/(library)/page.tsx) and offers a
link back to the first page. The row with the page title shows the total, "{N} items" plus any in
the trash, and the toolbar above the list shows how many this page holds, "{N} shown"
(apps/web/src/app/dashboard/(library)/page.tsx; joined-to-code: apps/web/e2e/library.spec.ts header counts).
Triage
Triage is the human's verdict, separate from the pipeline status: a click-cycle open to fail to
pass to open, the same cycle on web and desktop (TRIAGE_STATUSES in
packages/core/src/constants.ts:895, nextTriage in apps/web/src/lib/library/model.ts:655,
joined-to-code: model tests). It is exposed as a badge-shaped button whose hover title says
"Mark as {next}" (apps/web/src/app/dashboard/asset-actions.tsx:53).
In the trash the badge is display-only: triage still shows, but clicking it does nothing until the item is restored, matching every other write the trash hides (apps/web/src/app/dashboard/asset-actions.tsx, TriageBadge). The stoic pass fixed the earlier behaviour where it kept cycling there.
Backup and restore (desktop)
Backup writes one JSON file, named snapbuddy-backup-YYYY-MM-DD (apps/desktop/src/core.js:1202), containing every card: notes, statuses, thumbnails as data URLs, annotations with their time windows, file name and format choices, share links, and trash tombstones with their clocks. Recording video files are NOT inside it. A card restored on another machine reports honestly: "That recording is not on this machine any more: {path}" (apps/desktop/src/board.js:3057).
Restore ADDS cards, merging by id, and sanitizes everything: unknown fields dropped, share links rejected unless http(s), annotations capped at 200, and trimmed/recovered/deleted_at whitelisted explicitly (joined-to-code: anno-survive-restore, tombstone, name/format and share-link harness checks).
Sentences a support agent can paste
"In your library on the web, deleted items wait in the Trash for 90 days. While something is in the Trash its share link does not work; restoring it brings the link back. After 90 days the item and its stored file are removed for good."
"Deleting a card never deletes the recording file; only Delete forever, or the 90-day purge, removes files."
"A backup carries your cards and notes, not the video files; keep the recordings folder itself if you need the footage."