The stack comes out — Kanban/Git/ deleted wholesale, ten thousand lines into history
Step 5 of strategy/01-git-excision.md: the seventeen dead engine files and the five remaining git test suites go (InertGitTests stays — the naming footgun is a Storage keeper). Two rescues ride ahead of the delete: HarvestedReceipt relocates to EchoLedger (the harvest surface outlives its git consumer; foundation for the deferred journal), and commentTimestamps joins the narrator it always served. The provider-swap purge test re-expresses over a git-free fake; the duplicate-id ladder keeps every pure historyRank pin and loses only the two ranker-driven ones. Resurrection point: tag pre-git-excision. 2,707 tests green. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -549,26 +549,6 @@ struct DuplicateIdentityDetectionTests {
|
||||
#expect(result.duplicateIdentities.map(\.winner) == ["\(Ident.lane1)/\(Dup.lower)"])
|
||||
}
|
||||
|
||||
/// The same straddle with git in the picture: an ⌥-drag restore leaves the *tracked* path in the
|
||||
/// trash, so the ghost is the one history knows — and still loses.
|
||||
@Test("A tracked ghost still loses to the untracked live card")
|
||||
func trackedGhostStillLoses() throws {
|
||||
let fixture = try makeBoard()
|
||||
defer { fixture.tearDown() }
|
||||
let live = try fixture.item("\(Ident.lane1)/\(Dup.lower)", Item.rich(order: "1024", title: "Fix login"))
|
||||
let ghost = try fixture.item(".trash/\(Dup.lower)", Item.rich(order: "1024", title: "Fix login"))
|
||||
try setBirth(live, date(1000))
|
||||
try setBirth(ghost, date(0))
|
||||
let ranker = BoardLoader.IdentityHistoryRanker { path in
|
||||
path == ".trash/\(Dup.lower)" ? 1 : nil
|
||||
}
|
||||
|
||||
let result = try BoardLoader.load(boardRoot: fixture.root, historyRanker: ranker)
|
||||
|
||||
#expect(result.duplicateIdentities.map(\.path) == [".trash/\(Dup.lower)"])
|
||||
#expect(result.model.lanes.first { $0.id.rawValue == Ident.lane1 }?.cards.count == 1)
|
||||
}
|
||||
|
||||
/// **The same preference governs a trashed lane sharing a live lane's UUID** — the ruling says so
|
||||
/// explicitly, and it needs no special case: a trashed lane is a `.trash/` entry like any other.
|
||||
@Test("A trashed lane loses to the live lane sharing its UUID")
|
||||
@@ -706,30 +686,6 @@ struct DuplicateIdentityDetectionTests {
|
||||
])
|
||||
}
|
||||
|
||||
// MARK: The history seam
|
||||
|
||||
/// The seam base can never fill: an injected ranker decides the winner ahead of the birth dates.
|
||||
@Test("An injected history ranker outranks the filesystem")
|
||||
func historyRankerDecides() throws {
|
||||
let fixture = try makeBoard()
|
||||
defer { fixture.tearDown() }
|
||||
let original = try fixture.item("\(Ident.lane1)/\(Dup.lower)", Item.rich(order: "1024", title: "Fix login"))
|
||||
let copy = try fixture.item("\(Ident.lane2)/\(Dup.lower)", Item.rich(order: "1024", title: "Fix login"))
|
||||
try setBirth(original, date(0))
|
||||
try setBirth(copy, date(1000))
|
||||
|
||||
// Without a ranker the older folder wins…
|
||||
#expect(try BoardLoader.load(boardRoot: fixture.root).duplicateIdentities.map(\.path)
|
||||
== ["\(Ident.lane2)/\(Dup.lower)"])
|
||||
|
||||
// …and with one that says the newer path entered history first, it does not.
|
||||
let ranker = BoardLoader.IdentityHistoryRanker { path in
|
||||
path == "\(Ident.lane2)/\(Dup.lower)" ? 1 : nil
|
||||
}
|
||||
#expect(try BoardLoader.load(boardRoot: fixture.root, historyRanker: ranker).duplicateIdentities.map(\.path)
|
||||
== ["\(Ident.lane1)/\(Dup.lower)"])
|
||||
}
|
||||
|
||||
/// Three copies of one card: two are withheld, one renders — and the notice folds.
|
||||
@Test("Three occurrences leave one standing")
|
||||
func threeCopiesLeaveOne() throws {
|
||||
|
||||
Reference in New Issue
Block a user