The full bullet list from Implementation card bf080d9a — both ruling
batches, including the three appended mid-session by 16ef377:
- 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
Add-git seeds a minimal .gitignore (.DS_Store) before the initial
stage — the seed rides "Initial board state" and .DS_Store never
enters history; an existing .gitignore (or a directory wearing the
name) is left alone forever, adoption and repo-nested seed nothing.
GitHousekeeping is the periodic loose-object repack: filesystem
enumeration of objects/<2hex>/<38hex> (never git_odb_foreach, which
would rewrite the whole database into a fresh pack each pass),
git_packbuilder_insert one oid at a time, additive pack write — and
deletion only after each oid is re-verified against the written
pack opened as a standalone one-pack odb with no loose backend. Any
failure returns before deleting; the worst case is a stray pack.
Nothing prunes, expires, or consolidates — existing packs
accumulate, recorded as the accepted cost of never rewriting
storage the app didn't write. GitHousekeeper schedules it: git's
own 6700 threshold, 8s after session activation (outlasting the
launch catch-up), background priority, skipped under pause states,
held locks, or an in-flight commit, never retried — the next open
tries again. Free tier composes none of it.
20 new tests: full-odb equality, per-oid survival, identical walks,
byte+mtime-identical refs/HEAD/working tree, whole-.git identity on
every declined pass, and deleting-never-forgets. 2394 tests / 412
suites green; InertGitTests untouched. Closes pro-m1-git-undo.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
GitHistoryProvider is the second HistoryProviding implementation:
its stack IS HEAD's first-parent ancestry, reseeded on load (redo
empty), re-synced to HEAD before every crossing so agents'
self-commits become the top and ⌘Z steps back exactly one commit;
any arriving commit clears redo (a heal-only window deliberately
does not). Restores are forward commits through the ordinary
signature path — GitRestoreOperation materializes only the
current-vs-target diff as working-tree writes and resolves no
reset/checkout symbol at all; heal commits are transparent
in-session (pointer passes over, restores exclude heal-owned paths,
identity carried on landed windows via PlannedCommit.kind →
GitLandedCommit). Subjects "Undo:/Redo: <crossed subject>"; menu
labels never nest in-session; the root commit is not a step
(crossing it would restore the empty tree).
Provider binding flips: makeHistoryProvider(store, tier, git) —
free binds native everywhere, Pro binds the git provider on git
boards and NOTHING on mode-none/repo-nested (the pair disables
through existing validation); add-git mid-session live-binds via
HistoryStore.didAddGit → bindHistoryProvider (the flip only ever
adds).
SessionSettleGate is the reusable Save All / Discard / Cancel step:
restores whose diff touches an open Edit session or raw-source
buffer gate on it (Save All applies with validation — a refused
buffer cancels the whole restore focused on the offender; Discard
reverts via CardBodyEditSession.discardBuffer and reconciles against
the working tree, deliberately skipping the second flush); untouched
sessions ride through undisturbed. Built for the branch-switch card
to reuse. BoardStore gains the async performWholesale sibling.
CardHistorySection fills the m6 EmptyView slot: read-only, newest
first, follows the card across lane moves by folder-component match
(the UUID is the identity — no rename detection), absent off git
mode and off Pro.
2332 tests / 403 suites green; InertGitTests untouched.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
The pro-m1 foundation card. SwiftGitX 0.4.0 (bundled libgit2, the
pathfinder's pin) joins the one target; new Kanban/Git/ holds
BoardGitMode (pure nearest-.git-wins detection, .git-as-file counts,
NSString ancestor walk), HistoryStore (@MainActor @Observable;
compose() is the tier gate — free tier gets no object, no detection,
no stat), GitRepository (scope-confined SwiftGitX handles: create =
init + HEAD forced to main + whole-tree "Initial board state" commit;
branch reads incl. unborn/detached; path-history ranks), GitIdentity
(derived default as a pure function + repo-local config reader — not
libgit2's merged ladder), and GitPathHistory (Mutex-guarded lazy
ranker). beginSession composes the git state beside the tier and
feeds BoardStore.makeIdentityHistoryRanker; git-mode loads pass the
git-backed IdentityHistoryRanker to BoardLoader. The popover's git
slot resolves a pure five-way matrix: free tier unchanged (absent /
BoardGitNote), Pro mode-aware — Add Git on mode none, honest prose on
repo-nested, read-only branch line on git. Provider binding
unchanged: both tiers still bind native until the undo/redo card.
42 new tests across 8 suites, all repositories built through bundled
libgit2; InertGitTests untouched and green. 2194 tests / 375 suites.
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY