Address strongly-recommended review items
Commit

-
discoverReachable now takes ctx and checks ctx.Err() at the top of every visit. Without it, Ctrl-C during the multi-minute discovery phase on kernel-scale repos was ignored — exactly the case the per-translate() check was added for.
-
writeLoose: document the durability tradeoff. No fsync, by design — convert-sha256 is a one-shot bulk operation, not incremental, processes millions of objects, and Run wipes the target on error so the only supported recovery is rerunning from clean state.
-
Target directory cleanup on error. ensureEmptyTarget refuses to write into a non-empty dir; without this fix, any failure after PlainInit left config/HEAD/refs behind and blocked a retry with no recovery hint. New deferred cleanup arms after PlainInit, disarms on success, and is suppressed by --keep-source-objects so users can inspect partial state. A --check failure also disarms cleanup since the conversion itself finished and the partial target is what the user needs to inspect.
-
hashPattern is now case-insensitive ((?i) prepended), and resolveMessageRef lowercases the input before lookup. An uppercase/mixed-case SHA1 reference in a commit or tag message is now rewritten the same as a lowercase one.
-
Check gained a Skipped bool. Skipped implies OK so callers gating on OK still treat it as non-fatal; callers needing a stricter audit signal can branch on Skipped first. Applied to the fsck-when-git-missing and HEAD-on-tags-only paths, with a "○" glyph in the progress output to distinguish from real passes.
Tests cover discovery cancellation, fsck skipped, uppercase hash rewrite, and the existing tag-only HEAD check rewritten against the Skipped field.
Entire-Checkpoint: 248018a9dd16