mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-11-03 13:55:30 -05:00
* Locked volumes L1: a volume that disappears goes offline The volume monitor marked a tracked volume offline only while detection still returned it, so a drive that vanished while the daemon was down, or a dataset whose key was not loaded, kept is_online = 1 and attach_library resolved its sources against the stale flag. The monitor now reconciles every tracked row against detection and marks a vanished volume offline, telling the volume index so sources on it detach or reattach without a restart. attach_library resolves against live detection when monitoring is on, corrects a disagreeing row in place, and falls back to the stored flag when it is off. Each mapped drive carries its mounted state, and a source on a drive that is away comes up detached with its map restored read-only, no watch armed and nothing dispatched at the directory left behind. sources.list reads attachment from the index instead of the root existing. KeyManager::close used a file named :memory: as its placeholder, which one process can only hold once; a second core closing in the same process left its secrets file locked for the next open. It now uses redb's in-memory backend. Acceptance runs on a loop-mounted ext4 image unmounted with its mount point left in place; the suite joins the acceptance group of xtask test-core and skips with a reason without sudo or a loop device. Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Locked volumes L2: attached means mounted Attachment was Path::exists on the source root, and an unmounted drive leaves its mount point behind as an empty directory that passes it. The volume index now refuses to dispatch anything at a path whose drive is detached or whose mount point is not a mount point (on Unix, its device is the same as its parent directory's), whatever the stored state says: the source walk, the whole-drive map, the coverage heal, the content identification pass and the thumbnail job all check before running, and the indexer and identification jobs check again at run so a job resumed from a previous session cannot slip past. sources.track refuses the mount point of a known volume that is not mounted instead of registering a second source over the parent filesystem. The mount point check applies to drives learned from a volume row or from detection; a directory a test tracks as a drive keeps working. The acceptance scenario unmounts a loop volume under a running daemon with detection still saying mounted, drops the snapshot so a forced heal wants a walk, and proves no walk or hash job runs, the store keeps every record, tracking the directory refuses, and the listing reports the source unmounted with its counts intact. Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Release the library lock on every shutdown path Library::shutdown returned early when the job manager could not pause a running job in time, leaving the lock file behind; the next process in the same hour then refused the library as in use. The acceptance run on CI hit this when the hashing pass was still running at the fixture's shutdown. The lock is now released after the inner shutdown whatever it returned, and the fixture waits for its queued jobs before stopping. Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Review fixes: scope volume rows to this device, keep away drives resolvable, check detected drives' mount points attach_library_with and the monitor's reconcile now read and write only this device's volume rows; the table holds every device's, and a peer's row resolved against local detection was both corrected in place and entered into the volume index at the peer's mount point. The reconcile pass logs a row it cannot write and goes on to the next instead of aborting the library's pass. locate keeps a drive that is away in its fallback, so a mapped drive with no source over it still serves its map read-only from its own partition rather than scratch, with the mounted drive winning only at the same or a longer mount point. Drives detection returned are mapped through track_detected_volume, which carries their mount state and makes the mount point check apply to them; track_volume stays for cloud prefixes and the directories tests stand in for drives. The acceptance fixture waits for the hashing pass by its effect rather than by the running job list. Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Cloud volume roots are never refused as unmounted A cloud volume mounts at a service prefix such as s3://bucket, which detection never lists and Path::exists never answers for, so the mount guards read it as away and volumes.index refused every cloud volume. A cloud root is reachable as long as its row says so: attach maps it mounted without correcting its row, root_attached and dispatch_refusal pass it, and it never carries the mount point check. Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Stop the library watcher before closing libraries at shutdown The library directory watcher auto-opens a library whose lock file changes, and close_library removes the lock file, so a core shutting down reopened its own library from the watcher task and a core starting in the same process then found it in use. The acceptance job on CI hit this on every restart. The watcher now stops before the libraries close. Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Acceptance tests: say what the library and index hold when a source is missing Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Acceptance diagnostics carry a failed query instead of reading as empty Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Acceptance diagnostics list the open libraries Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> * Locked volumes acceptance fixture keeps the daemon's one library The core's volume index serves the library opened last and library load order follows the data directory listing, so a fixture with two libraries came up with an empty index on some runners. Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>
Spacedrive Documentation
The Spacedrive docs site, built with Fumadocs on Next.js. This directory is a standalone app with its own bun install, separate from the repo workspace.
bun install
bun run dev # dev server on localhost:3000
bun run build # production build
Or from the repo root: just dev-docs / just build-docs. Requires Node 20+.
Layout
overview/,core/,extensions/,cli/,react/,gpui/: published MDX content, one sidebar tab per folder. Navigation order lives in each folder'smeta.json.app/,lib/,components/: the Next.js app. Pages are served from the site root, socore/jobs.mdxrenders at/core/jobs.public/: images, logo, favicon.plans/,core/design/,design/,archive/: internal working docs, not part of the site.WRITING_GUIDE.mdx,CODE_COMMENTS.mdx: contributor guides, not published.
Writing pages
Frontmatter supports title, description, and sidebarTitle (a shorter name for the sidebar). Callouts, <Steps>, <Tabs>, <Cards>, and <Accordions> are registered globally, so no imports are needed in MDX. Every page is also served as raw markdown at <path>.md and indexed in /llms.txt.