Changes touching this path

  • Pass-2 candidate 5: unify the key=value config codec into loot-cli::kv ferry::parse_kv and workspace::parse_config_text were byte-for-byte identical (trim, skip #/blank, split_once('=') → BTreeMap), and three call sites hand-rolled the matching `{k} = {v}\n` encode (ferry::write_kv, Config::save, GlobalConfig::save). One `kv::{parse, encode}` module now owns the dialect; ferry (git_config / git_identity_map spine files), the per-repo .loot/config, and the global config all call it. Behaviour-preserving; the module carries its own round-trip/comment-skip/ordering tests (4). loot-cli lib suite green (227, +4 kv). This is the non-blocked core of pass-1's candidate 6 — pure text, no WipState → loot-cli-ledger cross-crate coupling. 9b171a5c · dbf3dbe6…

Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.