The seams unbind — the provider is always native, and the git stack compiles dead

Step 4 of strategy/01-git-excision.md, the entangled one: AppModel's makeHistoryProvider collapses to the native provider (the seam stays injectable per the reversibility posture), the session's git state and its wiring go (wireGitUndo, wireBranchSwitching, the card-session staging threading), BoardStore sheds commitSeam and the identity-history ranker (the loader's nil-safe rung now tops out at birth date — today's no-git behavior), SessionSettleGate keeps the gate and inherits the path utility it borrowed, BoardRegistry drops the persisted operation stamp (decode-safe), and the git banner family leaves BannerCenter with its announcer and accessibility phrases. One missed harvest tie severed (the narrator's root subject is its own now). Nothing outside Kanban/Git/ references the stack — proven by sweep. 2,855 tests green.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
2026-08-08 11:25:41 -04:00
parent f6a24132b6
commit cdba512512
24 changed files with 281 additions and 2567 deletions
-9
View File
@@ -432,13 +432,4 @@ enum AccessibilityPhrases {
/// Reload breakage clearing the board is reading its files again, which is a smaller claim
/// than the lock's and is deliberately phrased as one.
static let reloadBreakageCleared = "The board is loading again"
/// The unreadable repository clearing (06-history-undo.md Rules, ruled 2026-07-31: "the banner
/// clears when a later open or reload finds the repo readable").
///
/// Stated as the regained capability, `readOnlyLockCleared`'s rule: what the user was waiting on
/// is history advancing again, not libgit2 changing its mind about a folder. It stays the
/// smaller claim of the two nothing about editing the board was ever blocked by this
/// condition, which is precisely what its own row says.
static let repositoryUnreadableCleared = "History is recording again"
}
+5 -7
View File
@@ -212,14 +212,12 @@ public final class CardBodyEditSession {
}
/// **Throws the buffer away and takes disk's word for it** the Discard branch of the
/// save-or-discard step (06-history-undo.md Branch switching: "Discard reverts buffers and
/// uncommitted saves to HEAD").
/// save-or-discard step (13-native-undo.md Undo routing; `SessionSettleGate`).
///
/// It reverts the *buffer* and ends the session; the uncommitted on-disk saves are the operation
/// behind the step's to undo, because only that operation knows which state it is restoring to
/// (`GitRestoreOperation.plan(at:target:excluding:reconciling:)` reconciles the card's folder
/// against the working tree for exactly this reason). Splitting it that way is what keeps the two
/// halves from being two answers able to disagree: one pass writes the card's files, once.
/// It reverts the *buffer* and ends the session; any uncommitted on-disk saves are the wholesale
/// operation behind the step's to reconcile, because only that operation knows which state it is
/// restoring to. Splitting it that way is what keeps the two halves from being two answers able to
/// disagree: one pass writes the card's files, once.
///
/// The pending debounce is cancelled first, which is the load-bearing half a surviving timer
/// would write the discarded text back over the restored card a moment later.