Commit Graph
149 Commits
Author SHA1 Message Date
rzen cfee4a4b41 The board learns to zoom — eight rungs on one ruler, and Actual Size is the untouched board
View ▸ Zoom In / Zoom Out / Actual Size (⌘+ / ⌘− / ⌘0): 75%–200% in eight
rungs, app-wide and persisted (the Show Comments precedent) — a viewing
comfort, not a property of any one board. The level travels as
BoardZoomContext in the environment, injected on BoardView alone so the
banner strip, search bar, sheets and popovers stay at the system size; the
environment is also what carries it through CardFaceView's equality gate,
which compares nothing that moves with the level. Every BoardMetrics figure
follows zoom.bodyPointSize — card and lane chrome, drag replicas and the
count badge, the resize handle, the trash column — and the drop registry
carries the ruler for event-time reads, with the autoscroller's three
reaches turning font-derived (reachSide named as the stripGap it always
equalled). Lanes still divide the window; zoom never moves the window or
its floor. The toolbar gains a catalog-only Zoom In/Out pair mirroring the
menu rows' predicate; zoom holds shut mid-drag (frozen geometry), each rung
announces itself to VoiceOver, and the render suite pins both invariants:
a rung repaints every face, a no-op Actual Size repaints nothing.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-07 11:22:02 -04:00
rzen d5ad21c3da The board wears a picture — background becomes a mapping, and the window chrome follows it under a thin frost
background is {color:, image:} and only a mapping at every level; the board's image paints the full window under a transparent title bar, with a thin-material frost strip keeping the chrome legible and the standard accommodations intact.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-07 10:15:03 -04:00
rzen 190a8e36f1 Search takes the center — the titlebar placement grammar ratified
Redesign card 6d5a97fd resolved off the 2026-08-01 live try-out: leading is
board identity, center is view controls, trailing stays the user's catalog.
centeredItemIdentifiers, not a flexible-space sandwich — centers against the
window, holds as catalog items install, reaches machines with a saved
arrangement; defaultItems and its pinned tests untouched. 03 records the
grammar and the accepted tensions (widget-vs-field budget in narrow windows,
HIG's trailing convention yielding).

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 22:13:55 -04:00
rzen 9766e1f61c The Colors panel joins the palette — the combo ratified, and each anchor composes the halves it needs
Four rulings close Redesign Contradiction 3452893f (2026-08-06): the in-app
escape hatch is ratified in full, reversing 2026-07-29's palette-only rule —
the combo's Other… opens the system Colors panel, a pick landing on a palette
color stores the name, anything else the hex. Free-picked colors change no
contrast story: they land on the same runtime ink computation hand-written hex
always got (10 amended to say so; no warning surface is owed). Anchor
ownership: the card sidebar's background story is the combo alone — the well
grid's background half stays with the other anchors (StyleEditorView gains
showsBackground beside showsSymbols; the popover's symbol half already went to
its inline SymbolPicker). Quick-style recents stay palette-vocabulary — a
panel pick never enters them.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 22:05:48 -04:00
rzen b1ea97c03e Locality means the board the drag was picked up from — a rename is not a departure
Minor ruled into 04 ▸ Cross-board copy: the Finder volume model — a
mid-drag rename of the source board carries the live drag with it (the
drag holds its source store's identity, never a frozen key, which would
let a board opened at the vacated path compare equal — the worse,
destructive failure). Until the carry ships the residue is recorded:
key follows folder, a mid-drag rename finishes a reorder as a copy —
cosmetic, seconds-bounded. Implementation filed.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 21:02:47 -04:00
rzen 1980570b27 The popover's two post-split postures named — the explanatory row and the mode-none door
Minors ruled into 03 ▸ the git-at-a-glance section: a single-branch
board's switch picker opens onto a disabled "No other branches" row —
teaching why it is empty and where creation went — and the Pro
mode-none section stays as header plus the Board Settings… door rather
than vanishing, the git story keeping its named place.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 21:02:47 -04:00
rzen b1aa0c4483 The parse memo's blind spot blessed on file — reachable, pinned, and still outside the app's care
Minor ruled into 02 ▸ the memoize ruling: a stamp-preserving rewrite is
a decision on file rather than a surprise in the field — git lives with
the same blind spot, the behavior is test-pinned, and the tightenings
(hashing, generation stamps) wait for a real-world defeat.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 21:02:47 -04:00
rzen 13388776e1 The squeezed search field's two answers blessed — expand in place, and the platform's own row
Minors ruled into 03 ▸ Toolbar: a space-constrained search item
collapses to a button still in the window and ⌘F expands and focuses it
— the strip fires only for a truly windowless field; and AppKit's
overflow row that widens the window is the platform's own second
answer, unsuppressable without destroying honest overflow — two
gestures, two honest resolutions, no contradiction.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 21:00:23 -04:00
rzen 2e0e8ae871 Three surface blessings said in sentences — depth in rounds, no root skips, the path carrier
Minors ruled into 01 ▸ The decision surface and Skip: (1) depth reveals
in rounds — a defective lane index leaves its subtree unwalked, so
deeper defects surface on the round after its repair, the collect-all
rule meeting an unreadable container; (2) Skip never names the root —
the case-by-case foreclosures are one general rule the loader polices,
a root skip entry ignored and the defect collected anyway; (3) the
skip's carrier is the defect's root-relative path — the string the row
displays and Reveal resolves, exactly what the user consented about.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:59:12 -04:00
rzen 639d9839bf The subtitle hides with the title, blessed — context survives everywhere but pixels
Minor ruled into 05 ▸ Window: the no-title titlebar collapses AppKit's
title/subtitle pair as one field, so board › lane hides with it. The
window is usually beside its board; title and subtitle keep feeding the
Window menu, Exposé, VoiceOver, and restoration. The live-update wiring
stands — a sidebar placement row is the named candidate if a visible
surface is ever wanted; deliberately not built now.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:57:47 -04:00
rzen e147e9cd96 The covering await baselines on bracket close — the racer window blessed academic
Minor ruled into 06 ▸ Auto-commit: a reload in flight at bracket close
clears the gate without a started-after guarantee, and the committer
deliberately does not ask — the cadence margin makes the window
academic, the post-bracket reload is unconditional, and the deadline
already accepts a near-covering snapshot; the tree is what gets staged,
so the exposure is message precision, never content. Walk-start
bookkeeping named as the escalation.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:56:50 -04:00
rzen d23ead4b27 Pro surfaces audit through a fixture-gated tier override — a toy sandbox, never a bypass
Issues card ruled into 10 ▸ audits: the every-surface claim reaches
tier-gated UI via a launch flag honored only when isFixtureLaunch is also
set — the fixture already scopes the app to a scratch container and a
throwaway board, so the override grants Pro on a disposable sandbox and
never over real boards. Manual-checklist-forever would asterisk the
claim; debug-only would leave release unauditable. Partial surfaces pin
the free-reachable state and audit the full one under the override.

(Carries 10's in-flight zoom-control bullet from the parallel session.)

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:54:18 -04:00
rzen d9b6232dea The lane plate's strays return to their anchors — the replica's wash leaves the height arithmetic it broke
The pathfinder surface stack landed in e1ffe71 entangled with staged-index
placement drift: the replica's wash block sat inside replicaHeight (a CGFloat
has no .background — HEAD did not build), the body plate rode outside the cut
dim, the lanePlate property and the DESIGN bullet sat away from their kin.
Pure relocation, no new lines: every block moves to the anchor it was written
for. Verified by an isolated build of this tree.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-08-06 20:54:08 -04:00
rzen e1ffe71e5b A refused trash hover withdraws the trash's own promise — the fall-through holds only keepable ones
Gap #12 ruled into 04 ▸ the trash-drop bullet: the refusal fall-through's
honest reading (the column declines to be a target, it does not cancel
the held drag) covers only promises the refusal leaves keepable — lane
shadows keep drawing and an ⌥-copy lands where they are. A standing
proposal naming the trash itself is the promise the refusal just broke,
so it withdraws: the drag goes proposal-less over the column, release
with no proposal cancels in agreement with the empty picture, and
lifting ⌥ re-asks at the same address. Implementation filed on the
Implementation board.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:48:45 -04:00
rzen 531ca2c595 Do-nothing guards read the pending truth — never-trust-memory is the render path's scope
Gap #11 ruled into 02 ▸ One-way flow: between a write's bracket and its
echo the snapshot describes the past, so a guard deciding whether a write
would change disk baselines on the snapshot as amended by this store's
own in-flight writes — a pending-value record of the write path's own,
never the EchoLedger. Relative gestures (step one width unit) resolve
their base against the same amended truth, and the undo step's recorded
prior reads it too. The amendment dies with its echo; failed writes never
enter it. Coalescing weighed and set aside — one gesture, one write, one
commit. Implementation filed on the Implementation board.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:46:39 -04:00
rzen 3fc3dc629a A drop under an active filter counts in the rendered space — the visible anchor rule
Gap #10 ruled into 04 ▸ Search's single-source-of-truth bullet: zones,
shadow, and write all resolve through the same filtered list — the
position the shadow shows is the landing the write performs. The slot's
meaning in the full order is its visible anchor (after the visible
predecessor, before the visible successor at the lane top, true end in a
query-emptied lane; multi-card in proposal order beside the anchor);
hidden cards keep their ranks untouched, and the gesture's meaning
survives the query's clearing. The rendered space includes the new-card
placeholder. Code diverges today — implementation filed on the
Implementation board.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:43:19 -04:00
rzen d9797acf57 The form rule and the banner rule compose — inline while the asking surface stands
Gap #9 ruled into 06 ▸ Rules: a board-wholesale operation asked from a
form is both rulings at once, and the form rule wins while the asking
surface is up — create-and-switch answers inline in the sheet's Branch
section, a picker-asked switch at the popover's caption, never both at
once (the sheet dismisses the popover). The banner stays the posture for
whatever outlives the asking surface — the form rule's own fallback
generalized. Banner-only-everywhere weighed and set aside.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:39:10 -04:00
rzen 3385ec61ee The two-counter split blessed — walks landed beside snapshots applied
Gap #8 written into 02 ▸ FolderWatcher's reconciling bullet: the
value-equal skip's structural consequence is that walk-subject consumers
cannot key on the applied-snapshot generation, so the store carries two
counters — applied (the committed-overlay hold's event, unchanged) and
landed (every successful reload, equal or not; failures bump neither).
The choosing rule: anything outside the snapshot, or about the walk
itself, watches landed walks — the comment thread, the comment search
index, the auto-committer's covering gate.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:37:42 -04:00
rzen 3c64e5ae68 The skip consent rides the session — reloads never relitigate a standing decision
Gap #7 blessed into 01 ▸ Malformed input ▸ Skip: the store retains the
open's skip set and every live reload's walk carries it, so a
still-broken skipped file never re-trips the reload-breakage banner. The
skip names a defect at a path, not the file — a fixed file rejoins
mid-session on its own, and a new defect at an unconsented path is
ordinary reload breakage. The notice stays the open's one-time residue;
consent lapses at close, and the next open meets the surface again.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:36:15 -04:00
rzen bb936068db The environmental carve-out — no walk to collect from, the welcome row answers
Gap #6 ratified into 01 ▸ Malformed input ▸ The decision surface: a root
that is gone/unreadable or is a file throws immediately as a single-defect
failure — nothing to walk, nothing a surface could repair or reveal — so
it retires to the welcome failure row on every open, attended or not.
Judged per failure, not per defect (the 31fee00 refinement, ratified): an
environmental defect among repairable ones still shows the surface, and
the vocabulary keeps the unreachable-root seat for the re-walk that meets
one under a standing surface.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 20:26:24 -04:00
rzen 52df210284 The fifth fail-fast class gets its row — a garbled schema is evidence, never a mint target
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 18:11:59 -04:00
rzen 503ec4872c Window-of-origin banner hosting reaffirmed — the board strip was an interim, naming survives it
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 17:28:51 -04:00
rzen ea15d1ac74 Every comment-trash purge kneels to the ownership gate — the container-whole retirement retires
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 17:10:09 -04:00
rzen a60d97689e The identity writer appends as 06 promised — clearing is the one sanctioned edit
Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-06 16:57:20 -04:00
rzen 8a8ec4dfd1 The two-homes width rule becomes focused-width parity
Ruled 2026-08-01: the width the user types in is the em-derived figure in
both of ⌘F's homes; the toolbar field's resting width is AppKit's, outside
the invariant — the transient strip never rests, so it has no collapsed
state to mirror. 03 also records the shipped grow-on-focus behavior beside
the default-item sentence.

Claude-Session: https://claude.ai/code/session_01CqjXB7ASoWtbyoGod68k97
2026-08-01 16:54:37 -04:00
rzen 16ef3779e8 Rule the session-commit await, switch-clears-stacks, and skip-purge decoupling
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 21:46:23 -04:00
rzen bc27a0cbd2 Bless the two-stack shape, the raw-apply omission, and name the coarse step
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 21:41:05 -04:00
rzen 01f1194a56 Gate the comment-trash sweep on live-step ownership
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 21:38:42 -04:00
rzen 9119aa1e9a Anchor session undo steps by card identity, not path
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 20:10:33 -04:00
rzen 25d2513ccc Repo-nested boards bind native undo in every tier
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 19:44:51 -04:00
rzen c0c741fe62 Bless the six 2026-07-31 minor findings
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 19:34:14 -04:00
rzen fecedab60d Split git setup out of the popover into a board settings sheet
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 19:22:45 -04:00
rzen 986347a95a Bless the reload parse memo and value-equal snapshot skip
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 19:15:51 -04:00
rzen cb87ea79c1 Gate relocation noise on a universally seeded .gitignore
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 19:06:14 -04:00
rzen 11981a2a99 Make order and schema optional below the board root
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 19:01:20 -04:00
rzen 3bd6187b94 Settle the fail-fast decision surface design
Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:44:41 -04:00
rzen 542ab169a3 Record the SHA-256 repository posture
Settled from the Redesign Minor card: SHA-256 repos are unsupported,
safely — unopenable ones take the corrupt-repo loud-failure path,
never a silent fall to mode-none; opened ones get hygiene's abstention
by construction (SHA-1 shape filter, empty work list). Recorded in 06.
No code change.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:32:30 -04:00
rzen 889f7ff5ce Bless pack accumulation as housekeeping's accepted cost
Settled from the Redesign Minor card: the hygiene pass never
consolidates, rewrites, or deletes existing packs — one pack per
threshold's worth of objects accrues forever, the never-rewrite
posture's price. Terminal git gc remains the consolidation path.
Recorded in 06. No code change.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:27:16 -04:00
rzen 34ee34aef6 Bless the housekeeping scheduling constants
Settled from the Redesign Minor card: loose-object pack at the 6,700
threshold (git's gc.auto default), 8 s after session activation,
background priority, skipped under contention, at most once per
session, all injectable. Recorded in 06's repo-growth bullet.
No code change.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:24:54 -04:00
rzen b8e4f83028 Bless the config writer/reader asymmetry
Settled from the Redesign Minor card: identity writes append a plain
[user] section, never editing existing sections or tool-specific
subsections; reads take the last plain-section value, git's own
semantics — so the append always wins without reformatting anything.
Recorded in 06's identity bullet. No code change.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:21:07 -04:00
rzen 56fad6b3b0 Bless the identity fields' visibility-scoped config poll
Two Redesign Minor settlements in 06: the popover's name/email fields
re-read repo config at 2 s only while visible (the watcher never
delivers .git, so the resync courtesy needs its own signal; focused
fields keep keystrokes); and the wholesale-bracket failure sentence
now defers to 02's hosted-by-window-of-origin rule — the card window
hosts its own strip, a ⌘Z pressed there fails there.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:14:30 -04:00
rzen 92f4d386f4 Bless the failure-surface split for git operations
Settled from the Redesign Minor card: popover-asked operations fail
inline at the form; board-wholesale brackets — branch switch and undo
restore named explicitly — fail as banner rows, red one-shot failures
per the same-day banner ruling. A switch's bounded lock wait can
expire long after the popover dismissed. Recorded in 06.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:13:14 -04:00
rzen 40746a0cbc Bless the failed abort keeping the operation stamp
Settled from the Redesign Minor card: the stamp clears on successful
abort only. A failed abort keeps it — the stamp is the sole evidence
the leftover is the app's own, and clearing on failure would orphan it
as somebody-else's forever. Recovery retries at next open or the 15 s
paused-state re-read. Recorded in 06. No code change.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:11:26 -04:00
rzen a5dbc88a3a Bless the 30-second bound on the git-lock waiting state
Settled from the Redesign Minor card: the waiting posture stays calm,
but the wait ends — 30 s (injectable), then the clean-failure path,
tree untouched, lock path named. Only a stale lock ever reaches the
bound; an eternal spinner holding the wholesale bracket is worse.
Recorded in 06's index.lock bullet. No code change.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:10:17 -04:00
rzen 2dc008e39f Bless create-and-switch running the full switch sequence
Settled from the Redesign Minor card: no at-HEAD fast path — the
"can't change the tree" proof fails under concurrent writers, and
pending work flushes onto the branch it was made on. One sequence,
no special case; recorded in 06's Branch switching intro. No code
change.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:08:50 -04:00
rzen 5d946a1076 Bless the synchronous flush-before-overwrite commit
Settled from the parked Redesign Minor card, with the user: 02's
hang-avoidance doctrine and 06's ordering guarantee genuinely conflict
at noteWillWrite, and the guarantee wins — rare, bounded, load-bearing,
reentrancy-safe only in the synchronous shape. Full semantic
composition stays on the path: the commit preserving somebody else's
version keeps its real subject. Carve-out recorded in 06.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 18:06:42 -04:00
rzen 167d3de68a Git-operation failures join the one-shot failure banner tier
Settled from the Redesign board's Gap card: the failure class gains a
message-carrying GitOperationFailure shape beside the BoardWriteError
one — error tone, failure rank, BannerCenter phrasing. A failed undo
restore, branch switch, or pull/push presents as the failure it is,
never as a warning-tone loss row; recovery notices stay warning-tone.
Code realign pending (both reportFailure wirings post loss rows today).

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 17:57:34 -04:00
rzen 4105d1ae7d Restore subjects compose the inverse instead of nesting
Settled from the Redesign board's Gap card: crossing a restore commit
post-relaunch emits the inverse prefix ("Undo: S" crossed -> "Redo: S")
rather than stacking "Undo: Undo: S". Semantically exact and caps
prefixes at one; cosmetic-only mislabel accepted for foreign commits
whose subjects happen to open with a prefix. Code realign pending in
the restore-subject composer.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 17:51:11 -04:00
rzen 0a1b5f657a The root commit is the undo stack's floor, not a step
Settled from the Redesign board's Gap card: crossing the parentless root
commit could only restore the empty tree, and the root is a baseline,
not a change-set. Undo bottoms out at the initial board state; the
reseed walk stops in the same place. The shipped GitHistoryProvider
already conforms.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 17:49:30 -04:00
rzen ade7d34cd8 Land the 2026-07-31 design-ruling sweep
Uncommitted ruling prose from the pro-m1 sessions, committed as found:
trash sorts newest-first by modified stamp (no rank minting); kind-blind
trash selection; native undo in every tier with the provider following
the board; session-coarsening for card-window stacks; column-major
masonry; changed-path channel (02); window-scoped comment-thread heals;
commit-message vocabulary growth; integrity commit author; signature
passed per-commit instead of repo config; repo-state validation
tightening; comments pane defaults on; draft close-failure guard;
deferred comment-trash purge; 2.0 ships only with pro-m1 (RELEASE.md).

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-31 17:49:18 -04:00