Commit Graph
6 Commits
Author SHA1 Message Date
rzen 4cf5f09d93 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
2026-07-28 15:55:40 -04:00
rzen 1020d9fca4 Remove the face carousel — one card presentation
03's resettlement reverses the pathfinder carry-over: the
selection-keyed dual presentation proved undesirable, so a card has one
presentation — selection changes styling, never geometry, and the
masonry never reflows on click. Deleted the carousel view (page dots,
glass underlay, scroll-tick monitor), the QuickLook thumbnail cache
(sole consumer), the pure paging/suppression rules, and the
sole-selected animation key — Motion now keys transactions on the
search query and the drop proposal only. The attachment chip stays as
the face's whole attachment story; viewing media is the card window's
job. No carousel state had leaked beyond the view layer.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-28 08:11:59 -04:00
rzen b4c90838b4 Build card faces with edge-accent styling
The card face becomes real: leading SF Symbol (card default doc.text,
tinted by a valid hand-written iconColor — schema yes, control no),
title or the quiet untitled placeholder, and a quiet paperclip when
the card has attachments — title-only by design, no body excerpt.
Color is the settled K1 edge accent, not a fill: background paints a
4pt stripe down the left edge, resolved through the ported pathfinder
palette (12 icon tints + 12 backgrounds carried over verbatim, plus
raw #RRGGBB[AA]); anything unresolvable paints nothing and stays on
disk exactly as written. The snapshot now carries each card's flat
attachment names — the loader's one read inside a card folder, shared
with the Writer's listing so the m5 carousel and m6 sidebar can never
disagree on order (Finder order, the Writer's existing comparator).
The face keeps its top-aligned structure so the sole-selection
carousel can expand inside the card without moving masonry neighbors.
18 new tests.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-27 13:48:50 -04:00
rzen 4418b7f981 Align the identity predicate with the ratified shape-only rule
Accept liberally, emit conservatively (764a4d4): the gate is 8-4-4-4-12
hex in any case and any UUID version — uuidgen and UUID().uuidString
print uppercase, and a strict lowercase gate would silently stray an
agent's standard-tool card. Identity comparison is UUID-value equality
everywhere: ItemID keeps its byte-faithful rawValue but equates and
hashes on the lowercased canonical form, and the writer's
import-boundary collision check canonicalizes, so a same-UUID arrival
spelled in another case remints instead of slipping past. The app still
mints only lowercase v4 and never renames to canonicalize.

Full suite 342 tests in 63 suites green. Two findings filed.

Claude-Session: https://claude.ai/code/session_018BjQRYBR6jQja3jCRi5S3A
2026-07-26 20:53:38 -04:00
rzen 31f7691062 Gate level detection on UUID folder-name shape
Only lowercase-hex 8-4-4-4-12 folder names are lane/card candidates;
anything else is a stray — skipped with a distinct warning, never
descended, never able to fail-fast a load. UUID-shaped folders keep the
prior contract (missing index skips, malformed frontmatter fail-fasts).
Design resolution from the Redesign board. +5 tests.

Claude-Session: https://claude.ai/code/session_018BjQRYBR6jQja3jCRi5S3A
2026-07-26 16:03:39 -04:00
rzen c7cc97aeec Define the board, lane, and card model types
Immutable snapshot value types encoding the frontmatter tables: ItemID
wraps the exact folder name (not Foundation UUID, which uppercases);
lanes/cards carry FieldValue-typed fields, display-ordered children
including flagged tombstones, and their full FrontmatterDocument so
unknown and reserved keys ride along uninterpreted. Boards are
identified by rootURL — package folders are human-named, not UUIDs.

Claude-Session: https://claude.ai/code/session_018BjQRYBR6jQja3jCRi5S3A
2026-07-26 15:40:45 -04:00