git/intake/main

docs: describe what the audit changed

Artist matching, promotion and staging cleanup, journal locking and the
library swap all behave differently now, and DESIGN.md said otherwise.
diff --git a/docs/DESIGN.md b/docs/DESIGN.md
index f829d4e..51d0a54 100644
--- a/docs/DESIGN.md
+++ b/docs/DESIGN.md
@@ -134,13 +134,39 @@ Verification before promotion checks count, codec, duration, tags, non-whitelist
and decodes the first, middle and last file. A failure at any point leaves staging
untouched.
+An album is built in a temporary directory beside its destination and moved into place with
+a single rename, so nothing half-written is ever visible under the real name. Replacing or
+merging an existing album moves the old one aside first and puts it back if the new one
+cannot land; a merge checks every name for a clash before it moves anything. The library
+copy is swapped the same way.
+
+Staging is cleared only after the album has been promoted, and a staged file that cannot be
+removed is reported without turning a finished archive into a failure. Cleanup removes the
+album's own folder, its leftover sidecars and any subdirectory it has emptied, and stops at
+the staging directory: an empty staging directory is the normal state, not clutter.
+
+If the album's destination is a directory that already exists, the new copy is filed
+alongside it as `<album> (2)`, and everything after that — the summary, the journal and the
+library built by the same run — uses the directory the album actually landed in.
+
## Artist folders
-Resolved from the archive tree, the journal and `artists.toml`, in that order, with fuzzy
-and romanisation matching. Every decision is remembered, so the same artist always lands
-in the same folder. Nothing is guessed silently: an unknown album or artist, an empty
-normalised name, or two titles colliding on one target name is a hard issue, and `--yes`
-refuses to proceed rather than inventing metadata.
+Resolved from the archive tree, the journal and `artists.toml`, in that order. An exact
+folder name, a recorded alias, or a romanised spelling is followed without asking; every
+decision is remembered, so the same artist always lands in the same folder.
+
+Similar-but-different names are *not* acted on. A fuzzy match ("Blur" vs "Blue", "The Cure"
+vs "The Cult", "RTL Artist" vs "Art Artist" — all at or above the 75% score) is listed
+interactively and can be chosen there, but it is never taken automatically: filing an album
+under another artist's folder is silent, passes every later check because nothing compares
+a folder name against `ALBUMARTIST`, and is permanent once the guess is written to
+`artists.toml`. An unattended run creates the folder the credit names and prints the exact
+`artists.toml` line to add if the two really are the same artist. A duplicate artist folder
+is visible in a directory listing; a wrong one is not.
+
+Nothing is guessed silently. An unknown album or artist, an empty normalised name, two
+different titles collapsing to one name, or two tracks that would be written to the same
+file are all hard issues, and `--yes` refuses to proceed rather than inventing metadata.
## State
@@ -148,6 +174,15 @@ One journal at `~/.local/state/intake/state.json`, keyed by the staging path, re
the phase, the archive and library directories, track count and the placeholder flag.
`library verify` reconciles it against disk; `library audit` compares the two trees.
+Every change to the journal is a read-modify-write under a lock file beside it, and each
+save lands through a uniquely named temporary file. Without both, two runs on one root
+each wrote back a snapshot taken before the other, so an album could be filed while its
+record vanished, and a save could fail on a temporary file another writer had already
+renamed away.
+
+A record is only deleted when the album it points at has gone. A run that fails is not
+evidence about an album recorded earlier.
+
## Interface
Bubble Tea v2 (`charm.land/bubbletea/v2`), Bubbles v2 and Lipgloss v2. Screens: browse,