Implement repository hygiene

Add-git seeds a minimal .gitignore (.DS_Store) before the initial
stage — the seed rides "Initial board state" and .DS_Store never
enters history; an existing .gitignore (or a directory wearing the
name) is left alone forever, adoption and repo-nested seed nothing.

GitHousekeeping is the periodic loose-object repack: filesystem
enumeration of objects/<2hex>/<38hex> (never git_odb_foreach, which
would rewrite the whole database into a fresh pack each pass),
git_packbuilder_insert one oid at a time, additive pack write — and
deletion only after each oid is re-verified against the written
pack opened as a standalone one-pack odb with no loose backend. Any
failure returns before deleting; the worst case is a stray pack.
Nothing prunes, expires, or consolidates — existing packs
accumulate, recorded as the accepted cost of never rewriting
storage the app didn't write. GitHousekeeper schedules it: git's
own 6700 threshold, 8s after session activation (outlasting the
launch catch-up), background priority, skipped under pause states,
held locks, or an in-flight commit, never retried — the next open
tries again. Free tier composes none of it.

20 new tests: full-odb equality, per-oid survival, identical walks,
byte+mtime-identical refs/HEAD/working tree, whole-.git identity on
every declined pass, and deleting-never-forgets. 2394 tests / 412
suites green; InertGitTests untouched. Closes pro-m1-git-undo.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-31 17:06:57 -04:00
parent 1f7d84bf64
commit a7f35a0e5a
7 changed files with 1180 additions and 12 deletions
+10
View File
@@ -184,6 +184,16 @@ public final class GitAutoCommitter {
public private(set) var commitCount = 0
public private(set) var lastCommitOIDs: [String] = []
/// **Whether a flush is running right now** the housekeeper's gate (`GitHousekeeper`,
/// 06 Repository hygiene).
///
/// A read of the same flag the engine already uses to keep two flushes off each other, published
/// rather than duplicated: the alternative a second mutual-exclusion mechanism between the
/// committer and optional maintenance would put a new way to *not* commit into the one path
/// that must always commit. The repack is safe beside a commit either way (`GitHousekeeping`
/// Concurrency); this is what lets it be polite as well.
public var isCommitInFlight: Bool { isFlushing }
// MARK: - Private state
/// Receipts copied out of the ledger at bracket close, keyed by absolute path. Cleared when a