Realign code with the 2026-07-31 findings-resolution rulings
The full bullet list from Implementation card bf080d9a — both ruling batches, including the three appended mid-session by16ef377: - Restore subjects compose the inverse, never nest: crossing "Undo: S" emits "Redo: S" and vice versa; parity, not stack depth, reads a legacy double prefix (GitHistoryProvider.restoreSubject). - Git-operation failures join the one-shot failure banner tier: BannerCenter.GitFailureBanner (undo/redo/branchSwitch/addGit), error tone at failure rank merged with write one-shots by recency; the postLoss compromise is retired at both AppModel wirings. - order/schema optional below the board root: append-at-end reading (ordered siblings first, folder-name tie-break among the order-less), schema reads 1, both coerce-tier logged; the root keeps its requirements. Ranks.resolvedOrders materializes finite ranks so models and placement math stay untouched; first Writer rewrite stamps a real rank on touch, placement against an order-less sibling stamps that sibling inline in the same bracket. Agent guide v10 teaches optional keys and zero-read filing. Hostile-YAML order shapes become coercion tests; Fixtures/Valid/optional-keys.kanban replaces the four retired Malformed boards. - .gitignore is the relocation-heal noise gate: GitignoreRules pure matcher (standard semantics, board-root file only), loader consults it once per walk so matched loose files keep the stray posture; seeded (.DS_Store + .*.lanework-*) at board creation and template instantiation, healed in when missing at open — repo-nested included; empty file honored, existing files never edited; the committer's obedience via libgit2 status is pinned by test. - Comments crash-residue sweep gates on step ownership: HistoryStep derives backing from its own undo expectations, backedContent unions both stacks, the sweep purges per-entry only what no live step owns. - Skip-purge decoupled (16ef377): a stale-skipped coarse step strands whole in NativeHistoryProvider.strandedSteps — still backing, retired only at session end; clean exits purge as before. - Coarse close step named "Changes to '<card>'"; the fine body-edit wording never leaks onto the board menu. - Branch-switch settle clears every open card window's fine stack on Save All and Discard alike; the empty fold registers no coarse step. - Close flush awaits its covering snapshot (quiesce + one generation bump, 1s bound), and an explicit flush now queues behind an in-flight one instead of skipping — the audit-caught interleaving could lose a close flush permanently when the debounce fired inside the close sequence; regression tests force both races. - Commit comment bullets sort chronologically by created, not UUID. - The production-unwired CardBodyEditSession.editSessionDidChange seam is deleted with its seam-only tests. - Composition-root pins: beginSession composes the committer with the store's own EchoLedger and binds the announcer (the miswire class). - Deliberate 06 conformance pass over every 2026-07-31-tagged sentence: fixed Change-custom-key subjects (the retired named generic was the only producer), the unbuilt Replace attachment vocabulary, heal commits now authored Lanework Integrity, the config reader scopes identity to plain [user] sections, add-git re-runs detection at create (a stale mode-none could initialize inside the user's repo), and add-git failures answer at the form or the banner. Structural residue filed on the Redesign board. 2554 tests / 439 suites green. Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
This commit is contained in:
@@ -25,6 +25,10 @@ import Foundation
|
||||
/// destination clause a commit subject carries has no place in a title that has to stay short enough
|
||||
/// for a menu row.
|
||||
///
|
||||
/// **One deliberate exception, and it is the only one**: `cardSession(_:)` names its card
|
||||
/// ("Changes to 'Fix login'"), because the coarse close step is the one phrase whose *scope* is what
|
||||
/// distinguishes it — see that member.
|
||||
///
|
||||
/// Pure, and its own type rather than a `String` built at each call site, because a phrase composed
|
||||
/// in eleven places is a vocabulary that drifts in eleven places.
|
||||
public enum HistoryPhrase {
|
||||
@@ -105,15 +109,37 @@ public enum HistoryPhrase {
|
||||
// MARK: The card-window session
|
||||
|
||||
/// **The coarse close step's phrase** — one card window's whole session, as the board's stack sees
|
||||
/// it: 13-native-undo.md ▸ Rules names it "Edit card 'Fix login'", so the menu title is the same
|
||||
/// verb and noun every other card edit uses, dropping the item clause a menu row has no space for.
|
||||
/// it: **"Changes to '⟨card⟩'"** (13-native-undo.md ▸ Rules, ruled 2026-07-31).
|
||||
///
|
||||
/// Deliberately *not* a new verb. The session is an edit to a card — the fine-grained things
|
||||
/// inside it (a comment posted, a colour chosen, a paragraph rewritten) are the window stack's
|
||||
/// story, and a board-level row that tried to enumerate them would be the "Mixed update" problem
|
||||
/// in a menu (06-history-undo.md ▸ Commit messages). It reads identically to a body-edit step
|
||||
/// because on the board's stack it *is* the card's edit.
|
||||
public static let cardSession = name(.edit, kind: .card)
|
||||
/// > "the session's net effect registers on the board stack as **one coarse step named
|
||||
/// > "Changes to '⟨card⟩'"** … the board row reads "Undo Changes to 'Fix login'": plural and
|
||||
/// > scope-flavoured, distinct from every fine verb, honest about folding many kinds; the fine
|
||||
/// > body-edit wording never leaks onto the board menu."
|
||||
///
|
||||
/// ### Why this one phrase carries its item
|
||||
///
|
||||
/// Every other phrase here drops the item clause a commit subject carries, because a verb plus a
|
||||
/// noun already says what the row is (the type's note). This step has no such verb: what it folds
|
||||
/// is a comment posted, a colour chosen, a paragraph rewritten, all at once, and a row that named
|
||||
/// any one of them would be lying about the other two — while enumerating them would be the
|
||||
/// "Mixed update" problem in a menu (06-history-undo.md ▸ Commit messages). So the *scope* is the
|
||||
/// phrase, and a scope is only legible when it names what it is the scope **of**.
|
||||
///
|
||||
/// ### It is not `Edit Card`, and that is the point
|
||||
///
|
||||
/// This member read `name(.edit, kind: .card)` until the ruling, and the fine body-edit step still
|
||||
/// does (`registerBodyEdit`) — two different steps on two different stacks, one row apart in the
|
||||
/// Edit menu, saying the same six characters. The board menu now says "Changes to 'Fix login'" and
|
||||
/// the window menu says "Edit Card": the coarse row names the session, the fine row names the
|
||||
/// gesture, and neither can be mistaken for the other.
|
||||
///
|
||||
/// - Parameter title: the card's title **as the step is registered** — `nil` renders the same
|
||||
/// placeholder the card's own window title bar renders ("Untitled" is a rendering, never a
|
||||
/// value — 03-board-ui.md § Card face), so a menu row and the window it came from name the card
|
||||
/// the same way.
|
||||
public static func cardSession(_ title: String?) -> String {
|
||||
"Changes to '\(title ?? "Untitled")'"
|
||||
}
|
||||
|
||||
// MARK: Composition
|
||||
|
||||
|
||||
Reference in New Issue
Block a user