Lanes delete into the trash — storage, loader, writer, and undo
Phase 1 of the lanes-in-trash card (2026-07-29 ruling, docs led the
code): lane delete is a move into .trash/ with the subtree intact,
arriving at top trash rank — no destructive delete remains outside
the trash.
TrashedLane opaque unit (id/schema/title/order/heldCards) beside
trash cards — deliberately not a Lane, so no card-shaped surface can
believe an empty subtree. Loader's trash walk trusts the kind VALUE
(lane → opaque unit w/ held-card count counted at the loader's own
unit; card → ordinary card; absent/unrecognized → UUID-children
shape, empty-kindless falls to card per 01's honest limit). Writer:
moveIntoTrash generalized with kind passed never derived (an empty
lane would re-derive as card), deleteLaneToTrash mints against the
whole-container rank ladder. Retired: migrateTombstonedLane (lane
deleted: now ignored — loads live, bytes inert, tolerate-tier
warning), removeLane, captureSubtree/recreateSubtree and the
subtree-snapshot machinery. Undo inverse = move back to captured
strip position, redo replays at captured trash rank. Purge walks
lane subtrees; TrashModel.Freight phrases confirms with lane freight
("…and its 5 cards"). ItemPath gains .trashLane; resolve interleaves
the trash by rank; SearchFilter matches lane rows by title only.
Trashed-lane card windows dismiss and pending cuts void via the
ordinary vanish rule — no new plumbing.
Phase 2 (rendering, selection grammar, drag, a11y, agent guide)
follows. Both schemes 1858 tests / 318 suites green.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -277,9 +277,12 @@ public struct BoardDiff: Sendable, Equatable {
|
||||
/// Whether anything the digest can see differs — the whole value while the trash is being
|
||||
/// walked, everything but the trash while it is not.
|
||||
///
|
||||
/// `trash` is the one `var` on `BoardModel`, which is what makes "everything except the trash"
|
||||
/// expressible as value equality rather than as a second field-by-field list that would go
|
||||
/// stale the moment the model grows a field.
|
||||
/// `trash` and `trashedLanes` are the two `var`s on `BoardModel`, which is what makes "everything
|
||||
/// except the trash" expressible as value equality rather than as a second field-by-field list
|
||||
/// that would go stale the moment the model grows a field. Both are cleared, for one reason: a
|
||||
/// trashed lane is trash, so churn among the rows must stay invisible while the column is hidden
|
||||
/// — a lane *entering* the trash is still seen, because it left `lanes`, which is the board side
|
||||
/// and is exactly the "1 lane deleted" event the user watched happen.
|
||||
private static func boardSideDiffers(
|
||||
_ old: BoardModel,
|
||||
_ new: BoardModel,
|
||||
@@ -290,6 +293,8 @@ public struct BoardDiff: Sendable, Equatable {
|
||||
var newSansTrash = new
|
||||
oldSansTrash.trash = []
|
||||
newSansTrash.trash = []
|
||||
oldSansTrash.trashedLanes = []
|
||||
newSansTrash.trashedLanes = []
|
||||
return oldSansTrash != newSansTrash
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user