The decision surface — a refused open becomes a live repair, in place

Phase 3 of the decision surface, completing the card (01 ▸ Malformed
input, settled 2026-07-31). An attended open's fail-fast walk transforms
the loading window's content into one aggregated surface — never a
sheet, never a chain: defects grouped by class, each class stated once
with its files listed (Reveal in Finder + Open in Editor per row), a
class-level default preselected, per-item override behind a disclosure.
Only honest choices: YAML and malformed-schema get Editor + Re-check
(Skip below the root); newer-than-app gets Skip alone and blocks the
board at the root; the two root repairs — minted index, schema: 1 stamp
— are defaults. Repair and Open applies fixes in one store-less write
bracket and re-walks: clean proceeds, remainder re-aggregates into the
same surface. Cancel and ⌘W retire to welcome's row; restored opens
never see the surface at all (OpenOrigin rides the PendingOpen carrier).

Skips are per-open consent that rides the session — the store retains
the skip set and every reload passes it — and the opened board posts a
warning-tone notice naming what was left out, each item's Reveal riding
the banner strip's new reveal control. On Pro boards the repair bracket
binds its own EchoLedger, heal-marks everything, and the store adopts it
before the committer starts, so repairs land as one separate commit
authored Lanework Integrity — pinned end to end. Also fixed en route: a
retired loading window left its close interception installed and
returned false from windowShouldClose forever, blocking quit.

Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
2026-08-01 10:52:02 -04:00
parent 0933ac1b01
commit 31fee00c73
17 changed files with 2448 additions and 107 deletions
+26 -6
View File
@@ -197,21 +197,37 @@ public final class BoardStoreRegistry {
/// returns `nil` before constructing anything, so there is no store, no watcher, no entry and no
/// reference and the caller's security-scoped access is its own to release.
///
/// - Parameter skipping: **the decision surface's consented skips** (01-storage-format.md
/// § Malformed input, ruled 2026-07-31), passed to the walk and then *retained by the store*
/// so every reload of the resulting session runs with the same set (`BoardStore.skippedPaths`).
/// Empty the default is every board that opens without a surface.
///
/// - Returns: the board's store, or `nil` if this acquire was cancelled before its walk landed.
/// `nil` is not a failure: nothing went wrong and nothing was opened.
public func acquireOffMain(_ rootURL: URL) async throws(BoardLoadFailure) -> BoardStore? {
public func acquireOffMain(
_ rootURL: URL,
skipping: Set<String> = []
) async throws(BoardLoadFailure) -> BoardStore? {
if let store = referenceExistingBoard(at: rootURL) { return store }
// `nil` for a root that does not exist or whose volume will not answer there is nothing to
// coalesce on, so such an open walks alone and the loader produces the honest error for it.
let identity = FileIdentity(of: rootURL)
//
// **A skip-carrying acquire also walks alone**, deliberately: the single flight exists so
// concurrent opens of one board share a walk, and two walks are only shareable when they
// would produce the same answer. A skip set changes what the walk *finds*, so joining one
// would hand a window a board someone else's consent composed and a Repair-and-Open's
// re-walk could be answered by the very walk that failed. The condition is exactly "an
// ordinary open", which is every open the coalescing was built for (restoration, a Finder
// open racing it, a card window arriving first) and none of the surface's.
let identity = skipping.isEmpty ? FileIdentity(of: rootURL) : nil
let walk: Task<Result<LoadResult, BoardLoadFailure>, Never>
if let identity, let joined = walksInFlight[identity] {
Self.logger.debug("acquire: joining the walk already running for this board")
walk = joined
} else {
walk = Self.walk(rootURL)
walk = Self.walk(rootURL, skipping: skipping)
if let identity { walksInFlight[identity] = walk }
}
@@ -238,7 +254,8 @@ public final class BoardStoreRegistry {
case let .failure(failure):
throw failure
case let .success(result):
return try adopt(BoardStore(rootURL: rootURL, loaded: result), rootURL: rootURL)
return try adopt(
BoardStore(rootURL: rootURL, loaded: result, skipping: skipping), rootURL: rootURL)
}
}
@@ -246,10 +263,13 @@ public final class BoardStoreRegistry {
/// `BoardStore.startReload`'s reason exactly: a task created inside a `@MainActor` method
/// inherits that isolation and would run the walk on the main actor, which is the whole thing
/// this is avoiding.
private static func walk(_ rootURL: URL) -> Task<Result<LoadResult, BoardLoadFailure>, Never> {
private static func walk(
_ rootURL: URL,
skipping: Set<String>
) -> Task<Result<LoadResult, BoardLoadFailure>, Never> {
Task.detached(priority: .userInitiated) {
do throws(BoardLoadFailure) {
return .success(try BoardLoader.load(boardRoot: rootURL))
return .success(try BoardLoader.load(boardRoot: rootURL, skipping: skipping))
} catch {
return .failure(error)
}