Comments, phase 1 — storage, writer primitives, and the undo inventory
The kind: comment field table lands in IntegrityRules (the per-kind hook's first exercise), CommentThread reads one card's thread window-scoped (the board walk stays O(cards)), and CommentWriter gains the five gestures: draft save, post (rename .draft to a fresh UUID, created/modified restamped in the bracket), edit, delete into comments/.trash/, and the purge with its crash-residue memo. Post and delete register move-based undo steps; draft saves, edits, and the purge deliberately register nothing (13's no-capture rule). Copy boundaries strip comments/.trash, carry .draft verbatim, and remint threads; comments graduates to a displacing claimed name, with .draft, .trash, and a comment's attachments claimed one level down. CommentPath classifies changed paths into the 06 verb family for later announcer/composer wiring. One stated narrowing pending a ruling (filed on the findings board): the copy transaction's refuse-whole preflight stays cards-and-lanes — an unstampable copied comment copies verbatim with a log line, because comment defects never refuse. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -106,8 +106,23 @@ enum BoardTreeCopy {
|
||||
throw .failed(url: source, error: error)
|
||||
}
|
||||
|
||||
// The one exclusion this walk makes without being asked (01-storage-format.md § Enhanced
|
||||
// schema: `comments/.trash/` is "**stripped at every copy boundary** (clipboard staging,
|
||||
// Duplicate, Save as Template) — a copy must not carry ghosts no window session will ever
|
||||
// purge"). Unconditional because all three of this walk's callers *are* copy boundaries, and
|
||||
// an opt-in flag would be three call sites agreeing to one rule instead of one rule.
|
||||
//
|
||||
// It is the one depth-sensitive exclusion, hence the parent check rather than a name in
|
||||
// `excluded`: `.trash` at a board root is the board's own and carries or not per each flow's
|
||||
// stated exclusions, while `.trash` inside a `comments/` is undo's backing store and never
|
||||
// travels.
|
||||
let isCommentThread = source.lastPathComponent.lowercased() == IntegrityRules.commentsFolderName
|
||||
|
||||
for entry in entries.sorted(by: { $0.lastPathComponent < $1.lastPathComponent }) {
|
||||
guard !excluded.contains(entry.lastPathComponent.lowercased()) else { continue }
|
||||
guard !isCommentThread
|
||||
|| entry.lastPathComponent.lowercased() != IntegrityRules.commentTrashFolderName
|
||||
else { continue }
|
||||
|
||||
// Between items, never mid-item: this is the whole of "checks cancellation between
|
||||
// items", and the reason the copy is a walk at all.
|
||||
|
||||
Reference in New Issue
Block a user