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:
@@ -119,7 +119,8 @@ public final class BoardStoreRegistry {
|
||||
|
||||
/// The store for `rootURL`, opening the board if this is the first window to ask for it.
|
||||
///
|
||||
/// **First acquire**: loads the board (fail-fast — the `BoardLoadError` is rethrown untouched,
|
||||
/// **First acquire**: loads the board (fail-fast — the `BoardLoadFailure` is rethrown untouched,
|
||||
/// every collected defect included, because the decision surface is the caller's to host —
|
||||
/// because there is nothing to render and nothing to fall back on), then creates and starts the
|
||||
/// watcher and ties the two together in both directions — watcher events into
|
||||
/// `BoardStore.handleWatcherEvent(_:)`, the store's write brackets out to
|
||||
@@ -136,7 +137,7 @@ public final class BoardStoreRegistry {
|
||||
///
|
||||
/// A failed load leaves **nothing behind**: no entry, no watcher, no count. A board that failed
|
||||
/// to open is not open.
|
||||
public func acquire(_ rootURL: URL) throws(BoardLoadError) -> BoardStore {
|
||||
public func acquire(_ rootURL: URL) throws(BoardLoadFailure) -> BoardStore {
|
||||
if let identity = FileIdentity(of: rootURL), var entry = entries[identity] {
|
||||
entry.referenceCount += 1
|
||||
entries[identity] = entry
|
||||
@@ -167,7 +168,8 @@ public final class BoardStoreRegistry {
|
||||
// out. The loader's own vocabulary says it; no new error path is invented for a case that
|
||||
// means exactly what `unreadableRoot` already means.
|
||||
guard let identity = FileIdentity(of: rootURL) else {
|
||||
throw BoardLoadError(path: ".", reason: .unreadableRoot(message: "the board root has no file identity"))
|
||||
throw BoardLoadFailure(
|
||||
BoardLoadError(path: ".", reason: .unreadableRoot(message: "the board root has no file identity")))
|
||||
}
|
||||
|
||||
// Both directions of the wiring capture weakly, and the registry's entry is what keeps the
|
||||
|
||||
Reference in New Issue
Block a user