The paper agrees with the code — guide v11, README, DESIGN re-rulings, and the adjudicated sweep

Step 7 of strategy/01-git-excision.md, the companions. The agent guide bumps to v11: the Git section teaches repo-resident etiquette alone (stage only your own paths, commit your own changes, leave app-maintained files to the app) — existing boards heal to the new text on next open. README re-anchors: the four git feature bullets out, tiers say the complete Mac experience is free, and one bullet states the format's git-friendliness promise. The changelog drops the never-shipped git entries. DESIGN re-rules: 06 retired with Undo routing migrated to 13 (now the sole substrate's doc, seam kept open), 07 retired as written pending the ops-service workstream, 14 retired as superseded record, 12 carries the second pivot note, the index reflects all of it; the charter gets a pointer note (the anchors' full re-ruling stays with the user). InertGitTests renames to GitAgnosticStorageTests — the excision restores its original claim app-wide. And the sweep: ~70 comment sites across 36 files adjudicated against the keeper list, every present-tense description of the excised machinery made past tense or repointed, keepers untouched. 2,707 tests green.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
2026-08-08 12:31:27 -04:00
parent 8cf1457814
commit 445d035a83
50 changed files with 397 additions and 313 deletions
+70 -61
View File
@@ -442,9 +442,10 @@ public final class BoardStore: HealHost {
/// answer to "which ledger is this board's", and a second one would be a second provenance.
///
/// Its consumers today are the announcer's digest and the vanishing-focus sentence, both
/// through `land`. Pro's auto-committer (06-history-undo.md) becomes the second one without
/// this line changing which is why the type lives in `LiveStore/` beside `BoardDiff` rather
/// than inside the git provider.
/// through `land`. The foreign-change journal is slated to become the second one without this
/// line changing (`strategy/01-git-excision.md` Successors) once the auto-committer's job,
/// before app-managed git was excised 2026-08-08 which is why the type lives in `LiveStore/`
/// beside `BoardDiff` rather than inside any one consumer's module.
@ObservationIgnored
public let echoes = EchoLedger()
@@ -668,9 +669,11 @@ public final class BoardStore: HealHost {
/// raised lock above the completion), and the phrase must not survive to be spoken by some
/// later, unrelated reload.
///
/// **`nil` on every free-tier bracket today.** The free tier has no git operations, and the design's
/// examples ("Pulled 3 commits", "Switched to branch 'redesign'") are pro-m1's; the parameter
/// exists so that milestone supplies phrasing rather than re-plumbing the seam.
/// **`nil` on every bracket today.** App-managed git is gone (`strategy/01-git-excision.md`,
/// 2026-08-08) and nothing currently supplies a phrase the design's examples ("Pulled 3
/// commits", "Switched to branch 'redesign'") were git's. The parameter stays so a future
/// wholesale operation (the ops-based sync service `strategy/01-git-excision.md` Successors)
/// can supply one without re-plumbing the seam.
@ObservationIgnored
private var wholesaleCompletion: String?
@@ -1399,12 +1402,13 @@ public final class BoardStore: HealHost {
///
/// - Parameter completion: what to announce when the closing reload lands
/// (10-accessibility.md Live board announcements: "bracketed operations announce once, at
/// completion" "Pulled 3 commits", "Switched to branch 'redesign'"). `nil`, the default, is
/// an operation whose completion is not worth speech, which is **every free-tier bracket
/// today**: no git operations run there, and the two app-initiated writes that do reach disk on
/// their own the loose-file relocation and the legacy-tombstone migration are ordinary
/// `performWrite` calls that already say what they did on the banner strip. The parameter is
/// the seam pro-m1 fills; see `wholesaleCompletion`.
/// completion" "Pulled 3 commits", "Switched to branch 'redesign'", both git's). `nil`, the
/// default, is an operation whose completion is not worth speech, which is **every bracket
/// today**: app-managed git is gone (`strategy/01-git-excision.md`, 2026-08-08), and the two
/// app-initiated writes that do reach disk on their own the loose-file relocation and the
/// legacy-tombstone migration are ordinary `performWrite` calls that already say what they
/// did on the banner strip. The parameter is the seam a future wholesale operation fills; see
/// `wholesaleCompletion`.
///
/// - Throws: `BoardStoreWriteRefusal.readOnlyLocked` if the board is already locked a locked
/// board refuses to *start* wholesale work, not just ordinary writes. Otherwise rethrows
@@ -1484,8 +1488,7 @@ public final class BoardStore: HealHost {
/// Three ways this does nothing, all deliberate: a count below 1 clamps to 1 (a lane spans at
/// least one unit), an id that is not in the snapshot is ignored (the lane vanished under the
/// gesture the reload that removed it is the authority), and a count already equal to what the
/// lane displays writes nothing (a drag that ends where it started must not stamp `modified` or
/// mint a git commit).
/// lane displays writes nothing (a drag that ends where it started must not stamp `modified`).
///
/// Failures are already the banner's: `performWrite` posts every `BoardWriteError` before it
/// rethrows, so the rethrow is swallowed here rather than propagated to a gesture that has no
@@ -1519,7 +1522,7 @@ public final class BoardStore: HealHost {
/// The one commit point every width mechanism shares the edge drag, the context-menu stepper,
/// and the menu items' batch. One `performWrite` bracket whatever the count: one gesture, one
/// app-mediated reload, one commit on git boards (the style batch's rule).
/// app-mediated reload (the style batch's rule).
///
/// **A width landing on 1 removes the `width` key** (03-board-ui.md § Lane, settled the
/// remove-at-default family beside the empty rename's `title` and the None well's
@@ -1674,13 +1677,14 @@ public final class BoardStore: HealHost {
/// row with them.
///
/// **One bracket, whatever the target set's size.** "Choosing a well applies to the whole
/// selection one gesture, one commit on git boards" (§ Controls), so every target's `index.md`
/// is rewritten inside a single `performWrite`: the churn rounds back as one app-mediated reload,
/// and the auto-committer (m7) sees one operation rather than N.
/// selection one gesture, one write" (§ Controls), so every target's `index.md`
/// is rewritten inside a single `performWrite`: the churn rounds back as one app-mediated reload
/// once one operation for the auto-committer too (m7), before app-managed git was excised
/// entirely (`strategy/01-git-excision.md`, 2026-08-08).
///
/// **No-ops are skipped per dimension and per target** `setLaneWidth`'s rule, for its reason: a
/// well clicked twice, or a batch where half the cards are already that colour, must not stamp
/// `modified` or mint a commit on the items that were already right. A dimension whose value is
/// `modified` on the items that were already right. A dimension whose value is
/// already what the gesture asks contributes nothing; a target both of whose dimensions are
/// no-ops is dropped entirely; and a gesture that changes nothing anywhere never opens the
/// bracket at all.
@@ -1883,8 +1887,8 @@ public final class BoardStore: HealHost {
/// The image lands first and the frontmatter second, so a failure to write the picture never
/// leaves the board naming one that is not there. The reverse order would; the two are not atomic
/// together, and this is the ordering that makes the non-atomic half harmless. Both are inside the
/// same bracket, so the churn rounds back as one app-mediated reload and mints one commit on git
/// boards the style batch's rule, one gesture one commit.
/// same bracket, so the churn rounds back as one app-mediated reload the style batch's rule,
/// one gesture one write.
///
/// ### The name is chosen, not minted
///
@@ -2218,7 +2222,7 @@ public final class BoardStore: HealHost {
/// "Committing an empty rename on an existing item removes its `title` key"), rather than
/// writing `title: ""` titles are optional, and the face shows the untitled placeholder.
/// - **An unchanged title writes nothing.** `setLaneWidth`'s rule, for the same reason: an
/// editor opened and dismissed with Return must not stamp `modified` or mint a commit.
/// editor opened and dismissed with Return must not stamp `modified`.
///
/// The folder is re-derived from the *current* snapshot, which is what makes a foreign move
/// mid-rename invisible: the editor follows the UUID, and the write lands wherever the item is
@@ -2319,8 +2323,9 @@ public final class BoardStore: HealHost {
/// Ticks or unticks a Preview task-list checkbox **the app's one write into a card's body**
/// (05-card-window.md Preview), and otherwise an entirely ordinary one: the same
/// `performWrite` bracket, the same banner on failure, the same one-way flow back through the
/// watcher. "A toggle is an ordinary user edit the standard atomic write, auto-committed and
/// undoable on git boards."
/// watcher. "A toggle is an ordinary user edit the standard atomic write." (Once
/// "auto-committed and undoable on git boards" too; app-managed git is gone now,
/// `strategy/01-git-excision.md`.)
///
/// `bodyOffset` is the UTF-8 byte offset the parse handed the renderer (`BodyTask
/// .markerOffset`) and `checked` is the state the user was looking at; both travel to
@@ -2330,9 +2335,10 @@ public final class BoardStore: HealHost {
///
/// **It registers no undo step.** 13-native-undo.md Rules' inventory names the body write it
/// makes undoable precisely "Edit-session body save restore prior body bytes" and a Preview
/// checkbox is not one: it belongs to no session, has no flip to coalesce at, and 05 files it
/// under what is "undoable on git boards", which is the *other* substrate's answer. Registering it
/// here would be extending 13's inventory rather than implementing it.
/// checkbox is not one: it belongs to no session and has no flip to coalesce at. (05 once filed it
/// under "undoable on git boards" instead, the other substrate's answer; app-managed git is gone
/// now, `strategy/01-git-excision.md`, so a checkbox toggle is simply not undoable today.)
/// Registering it here would be extending 13's inventory rather than implementing it.
///
/// **A checkbox in a card that has gone writes nothing** the vanished-target guard every
/// gesture in this file makes, ancestor-walked through `boardItem`: the card window would be
@@ -2356,8 +2362,9 @@ public final class BoardStore: HealHost {
/// flush that closes the window (05-card-window.md Edit).
///
/// An ordinary store write in every mechanical respect: one `performWrite` bracket, so the churn
/// rounds back as a single app-mediated reload (and, on git boards, sits inside the session's
/// one commit see `CardBodyEditSession` for that seam); the banner posts itself on failure;
/// rounds back as a single app-mediated reload (once it also sat inside the session's one commit
/// on git boards see `CardBodyEditSession` for that seam, native-only now since the excision,
/// `strategy/01-git-excision.md`); the banner posts itself on failure;
/// the snapshot is never touched here, because the watcher's reload is what brings the text
/// back.
///
@@ -2605,7 +2612,7 @@ public final class BoardStore: HealHost {
/// name* (§ Board naming) never the "Untitled" placeholder cards and lanes show, and never
/// `title: ""`, which would be a real if blank title with nothing to fall back to.
/// - **An unchanged title writes nothing**, so a popover opened and dismissed with Return
/// neither stamps `modified` nor mints a commit.
/// does not stamp `modified`.
///
/// There is no vanished-target guard, because a board cannot tombstone itself out of its own
/// window (01-storage-format.md § Deletion): the only way this target goes away is the root
@@ -2652,8 +2659,8 @@ public final class BoardStore: HealHost {
/// exactly one file the moved lane's `order`.
///
/// **A drag that ends where it started writes nothing**: `index == from` re-inserts the lane in
/// its own slot, and a no-op must not stamp `modified` or mint a commit the resize drag's
/// rule, and for the same reason.
/// its own slot, and a no-op must not stamp `modified` the resize drag's rule, and for the
/// same reason.
public func moveLane(_ id: ItemID, toIndex index: Int) {
let lanes = snapshot.lanes
guard let from = lanes.firstIndex(where: { $0.id == id }) else { return }
@@ -2730,14 +2737,13 @@ public final class BoardStore: HealHost {
///
/// `moveLane`'s plural, and it exists rather than a loop over it because "one `performWrite`
/// bracket per gesture whatever the set's size" is load-bearing (DRAG-REORDER.md § The drop
/// commits): one app-mediated reload, and on git boards one commit rather than N.
/// commits): one app-mediated reload rather than N.
///
/// The run keeps **board order**, which is the lane level's flatten order a multi-lane drag has
/// no other relative order to preserve.
///
/// A drag that changes nothing writes nothing, stated as the arrangement rather than as a special
/// case: if the strip would render exactly what it renders now, no rank is rewritten and no
/// commit is minted.
/// case: if the strip would render exactly what it renders now, no rank is rewritten.
public func moveLanes(_ ids: Set<ItemID>, toIndex index: Int) {
let lanes = snapshot.lanes
let members = lanes.filter { ids.contains($0.id) }
@@ -2910,8 +2916,7 @@ public final class BoardStore: HealHost {
// produces their `index` is DRAG-REORDER.md's, implemented in `DropSlotMath`).
//
// **One `performWrite` bracket per gesture**, whatever the set's size the style batch's and
// the tombstone batch's rule, for their reason: one gesture, one app-mediated reload, one commit
// on git boards.
// the tombstone batch's rule, for their reason: one gesture, one app-mediated reload.
//
// **`index` always means the same thing**: a position among the destination's *rendered* items
// counted with the dragged run already removed the resting layout's own convention, so the
@@ -2920,7 +2925,7 @@ public final class BoardStore: HealHost {
// must not trap.
//
// **Ranks are inserted, never permuted.** A drop rewrites only the dragged items' `order`, so
// the siblings' files and `modified`, and a git commit stay honest about what actually
// the siblings' files and `modified` stay honest about what actually
// moved. That is the one place these differ from `sortSelection`, which permutes because its
// gesture is a permutation. `Ranks.insertionRanks` answering `nil` is the renumber trigger, and
// the fallback is `moveLane`'s: compact the destination, then place against the fresh ladder.
@@ -2928,8 +2933,8 @@ public final class BoardStore: HealHost {
// **Silent no-ops throughout**, all of them the reload being the authority rather than the
// gesture: a destination lane that is gone or tombstoned (04's "a card is never filed under a
// `deleted:` parent"), a dragged set emptied by a foreign reload, and a drop that lands exactly
// where everything already is (a drag that ends where it started must not stamp `modified` or
// mint a commit the resize drag's rule).
// where everything already is (a drag that ends where it started must not stamp `modified`
// the resize drag's rule).
/// One member of a dragged card set, resolved against the snapshot: **where it is now** a lane,
/// or the board's trash.
@@ -3507,8 +3512,7 @@ public final class BoardStore: HealHost {
/// `FileManager` call in the view: it mutates the card's folder, so the churn has to round back
/// as one *app-mediated* reload (the echo the watcher would otherwise read as a foreign edit),
/// it has to refuse under the read-only lock like every other mutation (`performWrite`'s gate),
/// and its failures have to reach the banner strip like every other write's. On git boards it
/// is also one commit, for free, for the same reason.
/// and its failures have to reach the banner strip like every other write's.
///
/// The guards are `importAttachments`' exactly, and its inverse in every way: **the board
/// container and only it** (`boardItem`), so a trashed card is as unreachable as a deleted one
@@ -3546,12 +3550,13 @@ public final class BoardStore: HealHost {
/// **It registers no undo step**, and unlike its neighbours that is not a deferral: nobody asked
/// for it. The relocation is the app tidying its own house on a reload, not a gesture there is
/// no Z that should follow it, and putting one on the stack would let the next Z undo something
/// the user never did. (It is `renumberVisibleChildren`'s posture: bookkeeping composes no event,
/// 06-history-undo.md Commit messages.)
/// the user never did. (It is `renumberVisibleChildren`'s posture: bookkeeping composes no event
/// once 06-history-undo.md Commit messages' rule, now the change narrator's,
/// `Kanban/Changes/ChangeNarrator.swift`.)
///
/// **One bracket over the whole board's worth of relocation**, so the churn rounds back as a
/// single app-mediated reload and (on git boards) a single commit the style batch's rule,
/// applied to a batch the app started itself. The snapshot is not touched here any more than it
/// single app-mediated reload the style batch's rule, applied to a batch the app started
/// itself. The snapshot is not touched here any more than it
/// is anywhere else: the files move, the watcher notices, the reload lands.
///
/// **The write half re-verifies against disk**: `BoardWriter.relocateLooseFiles` re-reads each
@@ -3728,13 +3733,13 @@ public final class BoardStore: HealHost {
/// Board Move Up / Move Down (/) the within-lane sort (04-interactions.md The map).
///
/// **One `performWrite` bracket**, like every other batch here: one gesture, one app-mediated
/// reload, one commit on git boards.
/// reload.
///
/// **The ranks are permuted, not invented.** The lane's existing `order` values, read in display
/// order, are already a sorted ladder of exactly the right length so the new ordering takes
/// them rung for rung and only the cards whose *position* changed are rewritten. A block stepping
/// past one sibling therefore touches the block plus that sibling and nothing else, which is what
/// keeps `modified` (and, later, a git commit) honest about what actually moved.
/// keeps `modified` honest about what actually moved.
///
/// The one case that ladder cannot serve is **duplicate `order` values**, where display order is
/// decided by the folder-name tie-break (`Ranks.isOrderedForDisplay`) rather than by the rank
@@ -3824,14 +3829,15 @@ public final class BoardStore: HealHost {
/// therefore whether a permanent delete stands an alert between one keystroke and unrecoverable
/// deletion (03-board-ui.md § Trash, "Both confirm exactly where the loss is real").
///
/// **Every board is `true` today**, because every board is history mode *none*: nothing in the
/// app keeps a second copy, so a purge is final everywhere.
/// **Every board is `true`**, because app-managed git is gone (`strategy/01-git-excision.md`,
/// 2026-08-08) and every board is history mode *none*: nothing in the app keeps a second copy, so
/// a purge is final everywhere.
///
// m7-git: git boards answer `false` here "on git boards they act immediately (delete-never-
// forgets)" (06-history-undo.md). Repo-nested boards stay `true` alongside mode none: the app
// manages no history for them either. The named predicate exists now so the committer card
// changes one expression rather than hunting the confirmation logic out of two menu items and an
// alert.
// Once slated for a `false` answer on git boards "on git boards they act immediately
// (delete-never-forgets)" (06-history-undo.md, retired) before the excision closed that door.
// Repo-nested boards stay `true` alongside every other board now: the app manages no history for
// any of them. The predicate stays a predicate rather than a literal at its two call sites
// regardless cheap insurance if a future substrate ever needs a `false` again.
public var purgeIsUnrecoverable: Bool { true }
/// **File Delete and its plain- grammar twin staged by place** (04-interactions.md
@@ -4323,8 +4329,8 @@ public final class BoardStore: HealHost {
/// `comments` is a tolerated stray until the feature consumes the name.
///
/// **One bracket over every displacement the load found**, whatever their levels: the batch is one
/// app-mediated reload and, on git boards, one heal commit the loose-file relocation's rule, and
/// this heal's own memo is board-wide anyway.
/// app-mediated reload the loose-file relocation's rule, and this heal's own memo is board-wide
/// anyway.
///
/// **Displacement, never destruction**, and never a mint: the freed name is left empty and the next
/// gesture that needs it creates the real folder the next delete mints `.trash/`, the next import
@@ -4483,9 +4489,11 @@ public final class BoardStore: HealHost {
// MARK: - The board's noise definition
/// Puts the seeded `.gitignore` on a board that has none, and does nothing at all to a board
/// that has one 06-history-undo.md Repository hygiene's whole scheduling ("a board missing
/// the file gains it by scheduled heal at open (the guide-refresh cadence)", re-ruled
/// 2026-07-31).
/// that has one the scheduled-heal cadence every heal in this file shares (02-architecture.md
/// Components HealScheduler): "a board missing the file gains it by scheduled heal at open (the
/// guide-refresh cadence)", re-ruled 2026-07-31. (06-history-undo.md Repository hygiene once
/// carried this rule under a git-flavored heading; the doc retired with the git excision,
/// `strategy/01-git-excision.md`, 2026-08-08 the noise-gate rule itself did not.)
///
/// **`refreshAgentGuide()`'s twin, deliberately**, down to the shape of this method: the file is
/// a board-root courtesy the app owns, its defect is *presence* rather than anything a tree walk
@@ -4502,7 +4510,8 @@ public final class BoardStore: HealHost {
/// 6), which is what makes a foreign deletion healable: the picture "missing" is restored by the
/// delete, and a standing memo would make that deletion the one thing this could not answer
/// while a failing write still gets exactly one attempt per changed picture rather than one per
/// reload. "Deletion is answered by re-seeding" is 06's own wording.
/// reload. "Deletion is answered by re-seeding" was 06-history-undo.md's own wording; the rule
/// survives the doc's retirement (`strategy/01-git-excision.md`, 2026-08-08).
///
/// **It registers no undo step**, like every heal: nobody asked for it.
public func seedGitignore() {