Changes touching this path

  • a forge storage error carries the server's own words, so a failed migration stops reporting 'db error' (#776) pg::storage formatted a postgres::Error with Display, which looks like it preserves the cause but is the literal string "db error" -- the message, SQLSTATE, detail and constraint all hang off as_db_error() and were dropped. connect_failed and migrate.rs's connect error had the same shape. That is worse than cosmetic. ForgeError::Storage is the ONLY ERROR-level variant, so the class the forge logs loudest carried nothing actionable; and --migrate funnels through it, so a failed migration reported 'storage: db error' with an empty ledger -- indistinguishable from the migration you had just written being wrong. Found applying ADR 0043's migration 0004 against a cluster that had defaulted to WIN1252: the real message named the offending U+26A0 byte sequence and the encoding, and was visible only in the postgres log on the box. It pointed the investigation at the new migration instead of at the cluster. pg::describe now unwraps as_db_error() into message/detail/hint/constraint plus SQLSTATE, and walks the source chain for non-DbError failures where Display is equally terse. All three sites route through it. It deliberately omits the statement and bound parameters: parameters carry tenant content and this string reaches logs. The server's message plus SQLSTATE names the fault without naming the data. before: cannot reach the metadata tier to migrate: db error after: cannot reach the metadata tier to migrate: database "nonexistent_db" does not exist [SQLSTATE 3D000] The regression test provokes a REAL server error rather than constructing one, because the bug was that the detail lives where Display does not look -- a hand-built ForgeError::Storage would have passed throughout this file's history. Verified to fail against the old one-liner. 9d4f91a6 · 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.