Files
lanework/DESIGN
rzen c87616f3fb Comments join attachments on the card face — a quiet bubble-and-count chip, present-only
A card whose thread holds one comment or more now draws a second trailing chip beside the
paperclip: a secondary-tinted bubble glyph plus its count, shown only when the count is above
zero (design ruling 2026-08-09, card e729e30a). Same styling family as the attachments chip —
caption size, secondary tint, decorative and hidden outright from the accessibility tree — but
this one carries a visible count rather than staying icon-only, per the ruling's own "bubble-style
SF Symbol + count." It sits after the attachments chip at the row's trailing edge, in both the
live title row and the drag replica.

The count is a new `Card.commentCount` field the loader fills with a readdir over `comments/`'s
identity-shaped children that carry their own `index.md` — `BoardLoader.commentCount(in:)`, built
on the same `identityShapedChildren` predicate a trash entry's held-card count already uses. Never
a parse: `.draft` and `.trash/` are excluded for free, the same dot-prefixed hidden-entry skip
`CommentThread.load` documents for both, so the walk stays exactly the O(cards) shape
01-storage-format.md § Enhanced schema already commits to. Because the count rides inside the
`card: Card` parameter `CardFaceView` already takes — not a new parameter of its own — drawing the
chip costs nothing beyond a field read on an already-compared value: no new Observable read joins
the body, and the equatable gate already covers it via `Card`'s synthesized `Equatable`.

The one divergence from the comments pane's parsed count is documented rather than hidden: a
comment folder whose `index.md` exists but fails to parse is a `Stray` the thread read excludes by
opening and rejecting it, a cost this readdir does not pay. The face may then read one comment
high until that folder is fixed or removed — the trade the ruling's "cheap directory-entry count…
not a parse" asks for, over paying full parse cost on every card of every load. Every well-formed
comment, and every card with no malformed one, agrees with the pane exactly.

VoiceOver: `AccessibilityPhrases.cardValue` gains a `comments: Int` parameter, appended after
attachments and before the cut-pending phrase — the same left-to-right order the two chips draw
in, so a sighted read and a VoiceOver read never disagree about which comes first. The trashed
lane row's own call site (an opaque unit with no comments to speak of) passes `comments: 0`.

Docs: DESIGN/03-board-ui.md's card-face section describes both chips and retires the stale "closed
with no growth" sentence, honestly recording the 2026-08-09 growth (the hero banner landed hours
earlier, this chip after it) as exposure of facts the card already carries rather than a body
excerpt. DESIGN/10-accessibility.md's flattened-element sentence gains the comment count.
DESIGN/01-storage-format.md's Enhanced schema paragraph records the chip as shipped. WISHLIST #9
is marked shipped in place — not renumbered, since #10 and #11 are cross-referenced elsewhere.

Tests: CardCommentCountListingTests (BoardLoaderTests.swift) pins the readdir against a synthetic
tree — no comments/ folder, an empty one, non-identity-shaped and index-less strays excluded,
.draft/.trash/ excluded for free, agreement with CommentThread.load's parsed count in the
well-formed case, and the one documented divergence on a malformed index.md.
AccessibilityPhrasesTests covers cardValue's new parameter alone, alongside attachments, and
all three fragments together. ViewEquatableTests pins that a comment landing on a card is a gate
difference. BoardRenderPerformanceTests adds a render-cost guard: one comment added to one card
on a hosted 180-card board re-renders a handful of bodies, not the board.

Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
2026-08-09 01:21:33 -04:00
..
2026-07-26 14:58:16 -04:00

Lanework — Design Documents

A ground-up rewrite of the Kanban app, to ship as Lanework on the Mac App Store. The old repo (../../Kanban, one level above this repository — not the rewrite's own Kanban/ source folder, which shares the codename) was a pathfinder — it never shipped, but it is the reference implementation and the source of hard-won decisions. This design starts from a clean slate and keeps only what earned its place. The rewrite keeps the internal codename Kanban (bundle id dev.rzen.indie.Kanban).

Each document covers one aspect of the design. Within each:

  • Decisions — settled, either carried over from the old app or newly made.
  • Changes from Kanban — where this rewrite deliberately diverges.
  • Open questions — flagged for iteration; nothing here is implicitly settled.

Index

Doc Aspect
00-vision.md What Lanework is, who it's for, goals and non-goals
01-storage-format.md On-disk contract: folders, frontmatter, ordering, the materialized trash
02-architecture.md App structure: source of truth, stores, watchers, concurrency
03-board-ui.md Board window: layout, lanes, cards, styling, templates
04-interactions.md Selection, drag & drop, keyboard, clipboard, search
05-card-window.md The card window: Markdown preview/edit, attachments
06-history-undo.md Git-backed undo/redo and history — retired 2026-08-08 (git excised, strategy/01-git-excision.md; Undo routing migrated to 13)
07-sync-collab.md Board modes and git-rails sync — retired 2026-08-08 as written; successor: the ops-based sync service workstream
08-agent-integration.md AI agents as first-class users of the board
09-templates.md Board templates: inventory and definition format
10-accessibility.md VoiceOver, text scaling, visual accommodations
11-command-nexus.md The command Nexus — every command and action: bindings, contexts, customizability
12-editions.md The tiers — mooted 2026-08-08: one version, everything free, tier machinery excised; Pro returns with the iPhone/sync era as a fresh pass (the doc is record: entitlement mechanics, distribution, the git rows)
13-native-undo.md macOS-native undo/redo — the history substrate (sole since 2026-08-08); owns Undo routing
14-git-operations.md Extracted pathfinder git-operations conclusions — retired 2026-08-08 (superseded record)

Deferred design iterations

The card window (05-card-window.md), toolbar (03-board-ui.md ▸ Toolbar), styling controls (03-board-ui.md ▸ Styling ▸ Controls), and comments (01 ▸ Enhanced schema + 05 ▸ The comments column — designed 2026-07-29, shipping post-2.0) each had their focused pass and are settled.

The authoritative list of open design passes is the findings board (Lanework Redesign.kanban ▸ Issues to Resolve) — this section stopped enumerating by hand after drifting twice. Standing examples as of 2026-07-29: the attachment-undo staging design and the EchoLedger foreign-undo bridge (both flagged in 13-native-undo.md), Teams' tracker integration (no design yet), the fail-fast decision surface (01 ▸ Refuse), and the drop-release settle presentation (03 ▸ Motion — deliberately last in line).

Wishlist

Ideas worth keeping but outside the committed design live in ../WISHLIST.md.

Terminology

The rewrite adopts lane as the canonical term for what the old app called a column (it's in the name: Lane-work). "Column" survives only when referring to the old app or to interior card-grid columns inside a wide lane.