Materialize the trash — storage layer
Phase 1 of the trash pivot: the file format learns .trash/. The loader parses the reserved root container — cards only, one shared parseCard for both containers so fail-fast, attachments, and verbatim documents are literally the same code; absent means empty; symlinks and lane-shaped nestings fall out as strays by construction. BoardModel grows snapshot.trash as a plain rank-ordered card list — the container has no identity to carry. Legacy deleted: keys keep flowing through the retiring flag path so every tombstone consumer stays green, and are additionally reported through LoadResult.legacyTombstones in the loose-file idiom for phase 2's migration scheduling — nothing vanishes from view before its folder has actually moved, which is also 01's lock-deferral posture. Writer primitives land value-passing: move to trash with caller-minted rank and the deliberate modified stamp, tombstone migrations that surgically remove the key, physical lane removal, per-card and whole-container purge that leaves strays verbatim, and byte-faithful whole-subtree capture/recreate for lane undo. Board-wide identity now spans the trash, so an import colliding with a trashed UUID remints instead of colliding. The watcher already delivered .trash events — isGitInternal tests a component, not a dot — now stated and pinned rather than relied on. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -634,6 +634,12 @@ public final class AppModel {
|
||||
/// not validity, so a malformed `deleted:` counts as deleted here exactly as it does everywhere
|
||||
/// else.
|
||||
///
|
||||
/// **`.trash/` is excluded by construction** (02-architecture.md § Per-board app state,
|
||||
/// re-grounded 2026-07-28 for the materialized trash): this walks `snapshot.lanes`, and the
|
||||
/// trash is `snapshot.trash` — a sibling container, never a lane — so no filter is needed and
|
||||
/// none could be forgotten. The flag walk above is the retiring half of the same rule, kept
|
||||
/// while boards written by older versions still carry `deleted:` keys.
|
||||
///
|
||||
/// Static and pure: it is a fact about a snapshot, and the close flush is the wrong place to
|
||||
/// discover a counting bug.
|
||||
public static func liveCounts(of snapshot: BoardModel) -> (lanes: Int, cards: Int) {
|
||||
|
||||
Reference in New Issue
Block a user