Make the card window the commit unit on Pro boards
Phase C of the two-level undo card: the committer stages around the
whole open card folder — comments included — so gestures in an open
window never land in interim commits; window close flushes the session
as one semantically-named commit ("Edit card 'X'" with the thread as
body bullets, "Mixed update — N changes to card 'X'" when events mix),
with the two-commit foreign/user split preserved and the
comments/.trash purge riding the same bracket. Comment gestures lose
their per-gesture commits structurally (they write inside the held
folder). Branch-switch settle releases every window's staging before
checkout and re-arms on resume.
Fixes two latent pro-m1 defects: the committer was composed without
the store's EchoLedger, so every production commit classified foreign
and was authored Lanework External; and interim flushes dropped
harvest receipts they had not spent, unvouching the session's own
writes at close. Also lands 06's mixed-subject re-ruling (the retired
"Update board" fallback) and phase B's two files missed by the
previous commit's pathspec.
2444 tests in 422 suites green.
Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -329,13 +329,15 @@ struct CommitMessageFoldingTests {
|
||||
#expect(subject(of: message) == "Move 2 cards")
|
||||
}
|
||||
|
||||
@Test("A genuinely mixed window is 'Update board' — with every event in the body")
|
||||
@Test("A genuinely mixed window says so — with every event in the body")
|
||||
func mixedWindowsFallBack() throws {
|
||||
// Re-ruled 2026-07-31: the bare "Update board" is retired. Two cards, so no shared item and
|
||||
// no name to keep — "Mixed update — N changes", never a shrug dressed as one thing.
|
||||
let message = try compose { fixture in
|
||||
try fixture.card(Ident.card1, in: Ident.lane1, order: "1024", title: "Fix logout")
|
||||
try fixture.card(Ident.card3, in: Ident.lane2, order: "1024", title: "Write tests")
|
||||
}
|
||||
#expect(subject(of: message) == CommitMessageEngine.mixedSubject)
|
||||
#expect(subject(of: message) == "Mixed update — 2 changes")
|
||||
#expect(body(of: message) == [
|
||||
"- Add card 'Write tests' to Doing",
|
||||
"- Rename card 'Fix login' → 'Fix logout'",
|
||||
@@ -419,7 +421,7 @@ struct CommitMessageBookkeepingTests {
|
||||
modified: "2026-07-31T12:00:00Z"
|
||||
)
|
||||
}
|
||||
#expect(message == CommitMessageEngine.mixedSubject)
|
||||
#expect(message == CommitMessageEngine.unnamedSubject)
|
||||
}
|
||||
|
||||
@Test("A renumber's rescale preserves sequence and composes nothing")
|
||||
@@ -430,7 +432,7 @@ struct CommitMessageBookkeepingTests {
|
||||
try fixture.card(Ident.card1, in: Ident.lane1, order: "16384", title: "Fix login")
|
||||
try fixture.card(Ident.card2, in: Ident.lane1, order: "32768", title: "Ship it")
|
||||
}
|
||||
#expect(message == CommitMessageEngine.mixedSubject)
|
||||
#expect(message == CommitMessageEngine.unnamedSubject)
|
||||
}
|
||||
|
||||
@Test("An on-touch heal's backfilled kind is not an event")
|
||||
@@ -441,7 +443,7 @@ struct CommitMessageBookkeepingTests {
|
||||
"---\nschema: 1\ntitle: Fix login\norder: 1024\nkind: card\n---\n\n"
|
||||
)
|
||||
}
|
||||
#expect(message == CommitMessageEngine.mixedSubject)
|
||||
#expect(message == CommitMessageEngine.unnamedSubject)
|
||||
}
|
||||
|
||||
@Test("A renumber batches with the insert that triggered it")
|
||||
@@ -721,7 +723,7 @@ struct CommitMessageCommentTests {
|
||||
let message = try compose { fixture in
|
||||
try fixture.file(Self.thread(Ident.card1, Self.commentA), Self.commentText("Note."))
|
||||
}
|
||||
#expect(message != CommitMessageEngine.mixedSubject)
|
||||
#expect(message != CommitMessageEngine.unnamedSubject)
|
||||
#expect(!message.contains("comments/"))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user