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:
@@ -101,6 +101,39 @@ public final class CardWindowUndo {
|
||||
writes[id] = write
|
||||
}
|
||||
|
||||
/// **Empties this window's fine stack, registering nothing** — the branch switch's settle step
|
||||
/// (06-history-undo.md ▸ Branch switching, ruled 2026-07-31).
|
||||
///
|
||||
/// > "The settle also clears each open card window's fine undo stack: pre-switch steps describe
|
||||
/// > the branch being left — Save All and Discard alike end with every window's stack empty, the
|
||||
/// > board-stack discard-and-reseed precedent one level down; the windows stay open, following
|
||||
/// > their cards onto the new branch with fresh stacks."
|
||||
///
|
||||
/// ### Closing the stack is not closing the window
|
||||
///
|
||||
/// This is the whole reason it is a method rather than a call to `stack.clear()` at the call site.
|
||||
/// A window *close* owes the board one coarse step folded from this stack
|
||||
/// (`BoardStore.registerCardSession`, `netEffect()`); a settle clear owes it nothing, because the
|
||||
/// window is not closing — it stays open on the other side of the checkout and its next gesture
|
||||
/// starts a fresh stack. So nothing here registers, nothing folds, and the fold that runs at the
|
||||
/// window's eventual close sees only what the *new* branch's session did: `netEffect()` reads
|
||||
/// `stack.pendingSteps`, which this empties, and `registerCardSession` answers `false` over an
|
||||
/// empty fold exactly as it does for a session with no net change.
|
||||
///
|
||||
/// The raw writes go with the steps. They are keyed by step id and nothing on either stack names
|
||||
/// them any more, so keeping them would be a table that only grows — and a redone step's half of
|
||||
/// the fold, which is the one reason the table outlives the undo stack, has nothing left to be
|
||||
/// half of once both stacks are empty.
|
||||
///
|
||||
/// **Nothing retires here that would not have retired anyway.** `NativeHistoryProvider.clear()`
|
||||
/// runs each dropped step's retirement, and a window's fine steps carry none: the deferred
|
||||
/// `comments/.trash/` purge is the *coarse* step's (13-native-undo.md ▸ Interaction with the
|
||||
/// trash), registered on the board's stack at close and never on this one.
|
||||
func discardSteps() {
|
||||
stack.clear()
|
||||
writes.removeAll()
|
||||
}
|
||||
|
||||
// MARK: - The fold
|
||||
|
||||
/// **The session's net effect, or `nil` when there is none** — what the window's close registers
|
||||
@@ -111,7 +144,11 @@ public final class CardWindowUndo {
|
||||
///
|
||||
/// - **undo** — every live step's undo, newest first. Replaying the session backwards lands on the
|
||||
/// state it started from, deleted comments included: their backing is still in
|
||||
/// `comments/.trash/` because this step's own existence is what defers the purge.
|
||||
/// `comments/.trash/` because this step's own existence is what defers the purge — and, since
|
||||
/// the sweep gate (13 ▸ Interaction with the trash, ruled 2026-07-31), what keeps the *next*
|
||||
/// window open from sweeping it as residue. That claim needs nothing of its own here: the fold
|
||||
/// below carries each delete's `.present(.trashedComment(…))` into the coarse step's
|
||||
/// expectations, and `HistoryStep.backing(declaredBy:)` reads it straight off them.
|
||||
/// - **redo** — every live step's redo, oldest first. The session, replayed.
|
||||
/// - **the undo's expectations** — the state the session's writes left, folded **last-write-wins**
|
||||
/// per field: what must still be true for the whole step to be safe to cross.
|
||||
|
||||
Reference in New Issue
Block a user