An unopenable repository fails loudly — the standing row, the paused surface, the honest heal

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
2026-08-06 18:44:12 -04:00
parent 52df210284
commit 0d8ecdb78b
20 changed files with 938 additions and 42 deletions
+26
View File
@@ -244,6 +244,21 @@ public enum BoardAnnouncer {
public var breakageBefore: BoardLoadFailure?
public var breakageAfter: BoardLoadFailure?
/// **The unreadable-repository condition before and after** (06-history-undo.md Rules,
/// ruled 2026-07-31: the standing breakage-class banner, "announced per
/// 10-accessibility.md"). Booleans rather than a payload for the row's own reason the
/// sentence is fixed and a pair rather than a single flag for the lock's: what is
/// announced is the *transition*, in either direction.
///
/// No reload ever sets these. The condition is detected at board open and healed by the
/// paused engine's own re-read, neither of which is a reload so its producer is
/// `BoardStore.noteRepositoryUnreadable(_:)`, exactly as the writability probe's lock is
/// `announceLockChange(from:)`'s. They live on this value anyway because the ladder is where
/// "one sentence, chosen by precedence" is decided, and a second announcer would be a second
/// voice.
public var repositoryUnreadableBefore = false
public var repositoryUnreadableAfter = false
public init() {}
}
@@ -304,6 +319,14 @@ public enum BoardAnnouncer {
if let breakage = facts.breakageAfter, breakage != facts.breakageBefore {
return AccessibilityPhrases.bannerLabel(tone: .error, headline: BannerCenter.headline(for: breakage))
}
// Last of the raised conditions, matching the strip's own precedence: the two above it
// describe the board's files, this one describes the history over them.
if facts.repositoryUnreadableAfter, !facts.repositoryUnreadableBefore {
return AccessibilityPhrases.bannerLabel(
tone: .error,
headline: BannerCenter.repositoryUnreadableMessage
)
}
return nil
}
@@ -316,6 +339,9 @@ public enum BoardAnnouncer {
if facts.breakageBefore != nil, facts.breakageAfter == nil {
return AccessibilityPhrases.reloadBreakageCleared
}
if facts.repositoryUnreadableBefore, !facts.repositoryUnreadableAfter {
return AccessibilityPhrases.repositoryUnreadableCleared
}
return nil
}
}