Denial is not absence — detection learns the unverifiable answer 06 ruled for it
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -323,6 +323,36 @@ struct HistoryStoreAddGitTests {
|
||||
#expect(git.mode == .none, "a refused add-git changes nothing, mode included")
|
||||
}
|
||||
|
||||
@Test("Create refuses a board that a fresh detection reads unverifiable — a denied ancestor")
|
||||
func createRefusesUnverifiable() throws {
|
||||
// **The tightened guard** (06 ▸ Rules ▸ Detection): "only a genuinely clean `.none` reading
|
||||
// proceeds" — a stale `.none` that has since become unverifiable is refused exactly like one
|
||||
// that has since become repo-nested (`createRefusesAStaleModeNone` above).
|
||||
let outer = try WriterFixture()
|
||||
defer { outer.tearDown() }
|
||||
let blocked = outer.root.appendingPathComponent("blocked", isDirectory: true)
|
||||
let boardRoot = blocked.appendingPathComponent("board", isDirectory: true)
|
||||
try FileManager.default.createDirectory(at: boardRoot, withIntermediateDirectories: true)
|
||||
try Data(Item.board.utf8).write(to: boardRoot.appendingPathComponent("index.md"))
|
||||
|
||||
try FileManager.default.setAttributes([.posixPermissions: 0o000], ofItemAtPath: blocked.path)
|
||||
defer { try? FileManager.default.setAttributes([.posixPermissions: 0o755], ofItemAtPath: blocked.path) }
|
||||
|
||||
#expect(BoardGitMode.detect(boardRoot: boardRoot) == .unverifiable, "the fixture is set up correctly")
|
||||
|
||||
let failure = GitRepository.create(at: boardRoot)
|
||||
guard case .failure(let reason) = failure else {
|
||||
Issue.record("initializing where detection cannot rule out a repository must be refused")
|
||||
return
|
||||
}
|
||||
#expect(reason.operation == "Adding git to this board")
|
||||
#expect(!reason.message.isEmpty)
|
||||
#expect(
|
||||
!FileManager.default.fileExists(atPath: boardRoot.appendingPathComponent(".git").path),
|
||||
"no repository created on an unverifiable read"
|
||||
)
|
||||
}
|
||||
|
||||
@Test("A failure answers at the form when it is up, and at the banner when it is not")
|
||||
@MainActor
|
||||
func aFailureAnswersAtTheFormOrTheBanner() async throws {
|
||||
|
||||
Reference in New Issue
Block a user