The loader collects every fail-fast defect and honors per-open skips
Phase 1 of the decision surface (01 ▸ Malformed input, settled
2026-07-31): BoardLoadFailure aggregates the walk's defects in walk
order — stop-at-first retires. Environmental failures (unreadable root,
not-a-directory) stay immediate single-defect throws: there is no walk
to collect from. A defective root index is recorded and the walk
continues into the children (nothing in the walk consults the parsed
root document — verified); a defective lane, card, or trash-entry index
records and skips its subtree, Re-check's whole-walk re-aggregation
being the designed loop for what hides beneath. load(skipping:) is the
per-open skip channel: a skipped path's item is omitted from the model
and surfaces as LoadWarning.userSkipped; root paths are unskippable by
construction. The reload-breakage banner carries the aggregate ("…and
N more"), single-defect sentences byte-identical to before. Two new
multi-defect fixture boards; suite 2591 green.
Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -345,7 +345,11 @@ struct UITestMalformedFixtureBoardTests {
|
||||
do {
|
||||
_ = try BoardLoader.load(boardRoot: root)
|
||||
Issue.record("the malformed board loaded — the fail-fast pass would audit a board that opens")
|
||||
} catch let error as BoardLoadError {
|
||||
} catch let failure as BoardLoadFailure {
|
||||
// One broken file, so one defect: the fixture breaks a single card's index, and the
|
||||
// aggregate is what the welcome row reads its caption off.
|
||||
#expect(failure.defects.count == 1)
|
||||
let error = failure.primary
|
||||
// The path is board-relative and names the *file*, which is what the welcome row's
|
||||
// failure caption carries and what the UI test asserts against.
|
||||
#expect(error.path.hasSuffix("/\(BoardLoader.indexFileName)"))
|
||||
@@ -360,10 +364,10 @@ struct UITestMalformedFixtureBoardTests {
|
||||
}
|
||||
|
||||
// The whole sentence, which is what actually reaches the user: file first, then why.
|
||||
#expect(error.description.contains(BoardLoader.indexFileName))
|
||||
#expect(error.description.lowercased().contains("yaml"))
|
||||
#expect(failure.description.contains(BoardLoader.indexFileName))
|
||||
#expect(failure.description.lowercased().contains("yaml"))
|
||||
} catch {
|
||||
Issue.record("expected a BoardLoadError, got \(error)")
|
||||
Issue.record("expected a BoardLoadFailure, got \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,10 +390,10 @@ struct UITestMalformedFixtureBoardTests {
|
||||
do {
|
||||
_ = try BoardLoader.load(boardRoot: root)
|
||||
Issue.record("the malformed board loaded")
|
||||
} catch let error as BoardLoadError {
|
||||
#expect(error.path.hasSuffix(BoardLoader.indexFileName))
|
||||
} catch let failure as BoardLoadFailure {
|
||||
#expect(failure.primary.path.hasSuffix(BoardLoader.indexFileName))
|
||||
} catch {
|
||||
Issue.record("expected a BoardLoadError, got \(error)")
|
||||
Issue.record("expected a BoardLoadFailure, got \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user