Give card windows their own undo stacks and coarsen the close
Phase B of the two-level undo card: every card-window gesture — comment
post/delete/edit, body Edit sessions, style and details changes —
registers fine-grained on the window's own stack (window.undoManager
answers with it; board ⌘Z never sees mid-session card steps; an empty
window stack beeps, never falls through). Window close folds the stack
into one coarse values-based board step ("Edit card 'X'") — per-target
per-field later-wins merge, so foreign mid-session writes stay out by
construction, a no-net-change session registers nothing, and any stale
component skips the whole step. The comments/.trash purge defers with
the coarse step via a step-retirement seam on the providers: it runs
when the step leaves the board stack or the board session ends; the git
provider retires dropped steps on register, which keeps Pro's
purge-at-close-flush structural with no tier check. Interim on git
boards: gestures still auto-commit per debounce until phase C's
close-flush commit.
2432 tests in 418 suites green.
Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -705,6 +705,22 @@ struct AgentGuideContentTests {
|
||||
#expect(!content.contains("Arrivals go on top"))
|
||||
}
|
||||
|
||||
/// **v9: values stay on one line** (2026-07-31 incident): a wrapped double-quoted `title` lost
|
||||
/// its continuation line in a hand copy between boards, leaving the quote unclosed — and an
|
||||
/// unclosed quote runs to the end of the block, so the whole file stopped parsing and the board
|
||||
/// refused to load. The guide has to teach the shape, say why copying it is where it breaks, and
|
||||
/// name the unterminated quote in Hard rules beside the colon it now shares billing with.
|
||||
@Test("v9 teaches one-line frontmatter values and names the unterminated quote")
|
||||
func v9OneLineValueVocabularyIsPresent() {
|
||||
let content = AgentGuide.content
|
||||
#expect(content.contains("**Keep every value on one line.**"))
|
||||
#expect(content.contains("swallow every key below"))
|
||||
#expect(content.contains("copy its frontmatter block whole"))
|
||||
// Hard rules names both classic violations, not just the colon.
|
||||
#expect(content.contains("The classic violations are an"))
|
||||
#expect(content.contains("quoted value left unclosed across a"))
|
||||
}
|
||||
|
||||
/// The pathfinder's guide taught `media/` and tombstone deletes; both are retired
|
||||
/// (01-storage-format.md ▸ Changes from the pathfinder schema; ▸ Deletion). The one legitimate
|
||||
/// mention of `deleted:` is the warning never to write it.
|
||||
|
||||
Reference in New Issue
Block a user