The tier axis comes out of the git stack — compose unconditional, postures mode-driven
HistoryStore.compose(boardRoot📒) returns non-optional and runs for every session — the nil the gate produced was the only nil it ever had. makeHistoryProvider is a one-axis decision: git-mode boards bind the git provider, everything else native, in every tier; Session.tier stays recorded, dormant. BoardGitSection shrinks to the four mode postures (.absent and .proPointer die, BoardGitNote and the .git probe with them); every board carries all three popover tabs (BoardInfoTab.available retired); the titlebar branch shows on any git-mode board; the settings sheet and card History section stop reading tier. InertGitTests is repurposed as UntouchedGitTests — the file layer still never opens .git, now load-bearing for mode-none boards. The accessibility audit reaches the settings sheet at last: the fixture board hosts it in every tier, so the free-fixture disabled-row test becomes an open-and-audit test. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -2,24 +2,37 @@ import Foundation
|
||||
import Testing
|
||||
@testable import Kanban
|
||||
|
||||
/// **The inert-`.git` posture, stated against real bytes on disk** (12-editions.md ▸ The free tier
|
||||
/// and `.git`): "any `.git` is inert — opening a board that has one works normally, but the app
|
||||
/// never reads history, never commits, never touches `.git` in any way."
|
||||
/// **The file layer never touches `.git`, stated against real bytes on disk** — every write and every
|
||||
/// load the app makes leaves the whole `.git` subtree byte- and mtime-identical.
|
||||
///
|
||||
/// It is unconditional app behaviour, not a build-time posture: the app that ships is the only app
|
||||
/// there is (12 ▸ The target, re-ruled 2026-07-30), and it runs this way for everyone without a
|
||||
/// subscription and for everyone whose subscription has lapsed — "unsubscribed and lapsed are one
|
||||
/// state". So these tests assert what `Kanban` does, full stop; nothing here is conditioned on a
|
||||
/// tier, and the git provider that will one day touch `.git` composes over its own boards.
|
||||
/// ### What this file used to be, and what it is now
|
||||
///
|
||||
/// Two halves of that posture are already pinned elsewhere and are referenced, not repeated:
|
||||
/// `FolderWatcherTests` ▸ ".git filtering" proves the watcher ignores churn under a `.git` at any
|
||||
/// depth, and `BoardLoaderStrayTests.strayFilesAndHiddenEntriesAreIgnoredWithoutWarning` proves a
|
||||
/// `.git` at the board root loads as an ordinary stray with no warning. Both are *input* claims:
|
||||
/// what the app does with events and entries it is handed.
|
||||
/// It was written as the **inert-`.git` posture**'s byte-level proof (12-editions.md ▸ The free tier
|
||||
/// and `.git`, as it then read: "any `.git` is inert … the app never reads history, never commits,
|
||||
/// never touches `.git` in any way"). **PIVOT 2026-08-07** retired that posture outright — git left
|
||||
/// the paywall, so a `.git` at a board root is *live* in every tier, detection runs at every open,
|
||||
/// and the auto-committer writes into exactly the directory this file's fixture plants.
|
||||
///
|
||||
/// This file states the **output** claim, which no existing test covers, and which is the one the
|
||||
/// posture has to be able to demonstrate: a full session of ordinary editing leaves every byte and
|
||||
/// The tests survive the retirement unchanged because none of them ever composed a `HistoryStore` or
|
||||
/// asserted anything about a tier: they drive `BoardWriter` and `BoardLoader` directly, and what they
|
||||
/// pin is that **those layers are git-agnostic**. That claim is not only still true, it is now
|
||||
/// load-bearing in two places the retired posture never reached:
|
||||
///
|
||||
/// - **A board nobody added git to** (mode `none`) is the one board the app manages no git for, for
|
||||
/// good — git stays opt-in per board (06 ▸ Rules; 13-native-undo.md's header read through the
|
||||
/// pivot). Nothing but this layer runs on such a board, so this layer's indifference *is* the
|
||||
/// whole promise.
|
||||
/// - **A `.git` the app does not manage** — a repo-nested board's ancestor, a clone dropped inside a
|
||||
/// card folder (which the fixture below plants deliberately) — is left strictly alone by the same
|
||||
/// indifference, whatever the board's own mode or the user's tier.
|
||||
///
|
||||
/// Two neighbouring claims are pinned elsewhere and are referenced, not repeated: `FolderWatcherTests`
|
||||
/// ▸ ".git filtering" proves the watcher ignores churn under a `.git` at any depth, and
|
||||
/// `BoardLoaderStrayTests.strayFilesAndHiddenEntriesAreIgnoredWithoutWarning` proves a `.git` at the
|
||||
/// board root loads as an ordinary stray with no warning. Both are *input* claims: what the app does
|
||||
/// with events and entries it is handed.
|
||||
///
|
||||
/// This file states the **output** claim: a full session of ordinary editing leaves every byte and
|
||||
/// every mtime under `.git` exactly as it found them. It is asserted the only way
|
||||
/// that is worth anything — by snapshotting the whole `.git` subtree from the filesystem before
|
||||
/// the edits and re-reading it afterwards, never through the app's own read path
|
||||
@@ -109,9 +122,11 @@ private func makeGitDirectory(in fixture: WriterFixture, under parent: String) t
|
||||
}
|
||||
|
||||
/// The board every test here edits: a root, two lanes, three cards, a `.git` at the board root
|
||||
/// **and** a second one nested inside a card folder (12: "any `.git` is inert", not just the
|
||||
/// root's own — a repo-nested board or a clone dropped inside a card is the same promise).
|
||||
private struct InertGitBoard {
|
||||
/// **and** a second one nested inside a card folder. Both, deliberately: the nested one is a `.git`
|
||||
/// the app never manages under any ruling (a clone dropped inside a card), and the root one is the
|
||||
/// case the pivot changed — it is a live repository to the *git* layer now, and still nothing at all
|
||||
/// to the file layer these tests drive.
|
||||
private struct UntouchedGitBoard {
|
||||
let fixture: WriterFixture
|
||||
let laneA: String
|
||||
let laneB: String
|
||||
@@ -144,12 +159,13 @@ private struct InertGitBoard {
|
||||
func tearDown() { fixture.tearDown() }
|
||||
}
|
||||
|
||||
// MARK: - The posture
|
||||
// MARK: - The claim
|
||||
|
||||
struct InertGitTests {
|
||||
@Suite("The file layer never touches `.git`")
|
||||
struct UntouchedGitTests {
|
||||
@Test("A full session of ordinary edits leaves every byte and mtime under .git untouched")
|
||||
func anEditingSessionNeverTouchesGit() throws {
|
||||
let board = try InertGitBoard()
|
||||
let board = try UntouchedGitBoard()
|
||||
defer { board.tearDown() }
|
||||
|
||||
let before = try snapshotSubtree(board.root, ".git")
|
||||
@@ -205,7 +221,7 @@ struct InertGitTests {
|
||||
|
||||
@Test("The board loads and renders normally with a .git at its root, without a warning")
|
||||
func aGitBearingBoardLoadsLikeAnyOther() throws {
|
||||
let board = try InertGitBoard()
|
||||
let board = try UntouchedGitBoard()
|
||||
defer { board.tearDown() }
|
||||
|
||||
let before = try snapshotSubtree(board.root, ".git")
|
||||
@@ -223,7 +239,7 @@ struct InertGitTests {
|
||||
|
||||
@Test("A nested .git rides along a card move byte- and mtime-verbatim")
|
||||
func aNestedRepositorySurvivesACardMove() throws {
|
||||
let board = try InertGitBoard()
|
||||
let board = try UntouchedGitBoard()
|
||||
defer { board.tearDown() }
|
||||
|
||||
let nested = "\(board.laneA)/\(board.cardWithRepo)/.git"
|
||||
@@ -250,7 +266,7 @@ struct InertGitTests {
|
||||
|
||||
@Test("A copy of a card carrying a .git reproduces it verbatim and leaves the original alone")
|
||||
func aCopyCarriesTheNestedRepositoryWithoutTouchingTheOriginal() throws {
|
||||
let board = try InertGitBoard()
|
||||
let board = try UntouchedGitBoard()
|
||||
defer { board.tearDown() }
|
||||
|
||||
let nested = "\(board.laneA)/\(board.cardWithRepo)/.git"
|
||||
|
||||
Reference in New Issue
Block a user