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
13 KiB
Tiers
Lanework ships as one Mac App Store app — dev.rzen.indie.Kanban, free, 2.0 updating the existing record — built from one codebase and one on-disk format, with Lanework Pro as an auto-renewable subscription unlocking the git tier. This doc owns the tier axis: what each tier is, how the gate is engineered (the provider seam, the entitlement), and which features land where. Individual docs stay tier-agnostic where they can — they conditionalize on board mode (none / git / git+remote — 07-sync-collab.md), and this doc defines which modes each tier ships.
Re-ruled 2026-07-30 — the one-app collapse. This supersedes the 2026-07-27 two-app split (separate base and Pro targets) and the 2026-07-29 App Group ruling that served it. The split's compile-time purity (base never links libgit2, no network entitlement) dragged permanent coexistence machinery behind it: a shared App Group, per-edition grant slots (security-scoped bookmarks never cross sandboxes), registry freshness stamping between two live processes, UTI-ownership twins, a both-apps-installed rulebook — a tax on every layer that generated a steady stream of design findings, all serving a state (two sandboxed apps sharing app-side state) that existed only because the packaging created it. One app makes that state unrepresentable. Costs accepted with eyes open: libgit2 rides dormant in the free download, and the one app declares the network-client entitlement (exercised only under Pro) — the "free app provably has no network access" story is traded for "no network use until you subscribe," which is honest but weaker.
The tiers
- Lanework (free) — no git integration. Boards are plain folders (mode
noneeverywhere); undo/redo is macOS-native (13-native-undo.md). The full board experience: lanes, cards, styling, trash, attachments, card window, templates, comments (when they ship), agents, accessibility. - Lanework Pro (subscription) — git integration as designed in 06-history-undo.md and 07-sync-collab.md: opt-in init, adoption, git-backed undo/history, branches, remotes, pull/push, auth. Plus Pro-only differentiators (matrix below).
- Lanework Teams — tracker integration over the reserved enhanced schema (
remote/remote-state, tracker-synced comment threads — comments themselves ship in every tier). Deferred — no design pass; probably a separate app when it comes. Whatever shape it takes, it will never share an app group or any cross-app state with Lanework (ruled 2026-07-30) — files are the only interchange this family recognizes.
The strategic reason for the seam stands unchanged (settled): Teams' card sync must be backend-agnostic — it has to work over git and over a range of trackers — so history and sync sit behind a genuine provider seam. The free tier's native undo is the first proof the seam is real: two working history providers before a third arrives.
Distribution (re-ruled 2026-07-30)
One record: dev.rzen.indie.Kanban, free, all territories, 2.0 as an update — the 1.x listing simply grows the subscription. The .kanban package UTI (dev.rzen.indie.kanban-board) is declared and exported once, by the one app — no ownership twins, no default-claim choreography. Lanework Pro is an auto-renewable subscription (StoreKit 2), purchased and managed in a Pro section of Settings (⌘,) — subscribe, manage, restore purchases. Teams' eventual monetization is deferred with Teams. 2.0 ships only when both tiers are ready (ruled 2026-07-31 — RELEASE.md): the Settings Pro section never faces a store without its product, so its unreachable state is only ever a true sentence.
No grandfathering (ruled 2026-07-30): 1.x shipped git-backed undo free; 2.0's free tier is native undo over the inert-.git posture (below). Existing users' boards keep working untouched, their histories stay intact and inspectable in any git client — the app just stops extending them until Pro is subscribed, and git resumes exactly where it left off (the committer's whole-root staging collapses the gap into one catch-up commit). No receipt-date logic exists.
The entitlement (ruled 2026-07-30)
- A local read, never a network call. Pro state is read from StoreKit's signed on-device transaction store at board-session composition — the open path gains no network dependency (02-architecture.md's hang-avoidance doctrine extends here). Offline with an active subscription is indistinguishable from online.
- Subscribe takes effect at each board's next open — the provider binding is a composition-time fact, the design the seam was built for. The purchase flow offers to reopen open boards so the upgrade feels immediate.
- A lapse never interrupts an open session: an open board finishes with the provider it composed; the next open composes the native stack over inert
.git. Unsubscribed and lapsed are one state — the inert posture, nothing lost, histories frozen not forfeited. - Offline grace resolves toward the paying user: an on-disk expiry passing while offline, with the last known state active and auto-renew on, holds the entitlement until StoreKit actually refreshes and answers. A cancellation (auto-renew off) lapses at expiry, offline or not. Either wrong-for-a-window direction costs nothing: a wrong lapse pauses auto-commits into one catch-up commit; a wrong hold gives away days of local commits — Apple's own billing grace makes the same trade.
- A fresh install that has never been online has no cached transactions and reads as the free tier until the first refresh — honest and self-correcting.
The provider seam
History (and later sync) is a provider behind one protocol boundary, bound per board session at composition from the entitlement:
- HistoryProviding — the undo/redo substrate. The provider follows the board (re-ruled 2026-07-31): gitless boards bind the native undo stack (13-native-undo.md: NSUndoManager over inverse
WriteOperations) in every tier — an upgrade never removes undo — while Pro binds the git provider on git boards (06-history-undo.md: undo as forward restore commits over HEAD's first-parent ancestry); repo-nested boards bind none. Teams inherits Pro's. Add-git swaps native → git mid-session by the branch-switch discard-and-reseed precedent (13). - Sync/tracker providers — deferred with Teams; the reserved schema keys and the one-way file flow (02-architecture.md) are the format-level seam already in place.
What is shared across providers (settled): 06's Undo routing is tier-independent — focus decides text-undo vs board-undo; only the substrate behind board-undo differs. The command surface is identical (⌘Z/⇧⌘Z, dynamically retitled menu items — both providers use NSUndoManager's title rewriting); menu titles draw on the same semantic vocabulary (06 ▸ Commit messages). A user subscribing (or lapsing) relearns nothing.
The free tier and .git — the inert posture (settled; now also the lapsed posture)
The free tier generalizes the repo-nested stance to every .git it meets: any .git is inert. Opening a board that has one (a formerly-subscribed user's board, a 1.x board, a repo-nested board) works normally — files read and write as on any board, native undo runs, the trash works — but the app never reads history, never commits, never touches .git in any way. To the free tier, .git at the board root is a stray like any other, preserved verbatim. Pro's external-writer machinery (06 ▸ Interaction with external writers) already reconciles the uncommitted drift a free-tier session leaves behind — a free-tier edit is just a foreign change to the git provider's next composition. The watcher's .git event filtering is unconditional (it exists to ignore git churn, which lapsed-and-resumed boards will produce).
The free tier's popover git slot (03-board-ui.md ▸ Board popover) does not offer add-git. Its posture is contextual (settled — ruled 2026-07-27, carried through the collapse): on ordinary boards the section is simply absent — the popover is rename + style, complete in itself. Only when the board carries an inert .git does a calm info line appear: "This board has a git history. Lanework Pro works with it." — an honest explanation of what the folder is, surfacing exactly where the question arises, never a standing ad; it is also the one in-context pointer to Settings' Pro section. The card window's absent History section follows the same pattern: absent, no placeholder.
Tier matrix
The feature sort. Everything not listed rides with "board experience" and is identical everywhere.
| Feature | Lanework (free) | Pro | Teams |
|---|---|---|---|
| Board experience: lanes, cards, drag & drop, keyboard map, clipboard, search, styling, trash, attachments, card window, templates, welcome screen | ✓ | ✓ | ✓ |
Agent integration: agent guide, modified-by attribution, tolerance rules |
✓ | ✓ | ✓ |
| Accessibility (10-accessibility.md, all of it) | ✓ | ✓ | ✓ |
| Comments (designed 2026-07-29 — 01 ▸ Enhanced schema + 05 ▸ The comments column; ships post-2.0) | ✓ | ✓ | ✓ + tracker-synced threads |
| Undo/redo | native (13) | git on git boards, native otherwise (06/13, re-ruled 2026-07-31) | inherits Pro |
| Undo of foreign/agent edits | — (honest gap, 13) | ✓ (stack absorbs foreign commits) | ✓ |
| Overwrite protection (flush-before-overwrite, both-versions-as-commits) | — (07's accepted caveat is permanent here; trash + native undo are the safety story) | ✓ | ✓ |
| History surfaces: card History sidebar (05), View ▸ History (11) | — | ✓ | ✓ |
| Git: init/adoption, branches, commit identity, repository hygiene | — | ✓ | ✓ |
| Remotes: pull/push, push-on-commit, auth (Keychain, SSH, TOFU) | — | ✓ | ✓ |
| "While you were away" digest (WISHLIST item 1, requires git) | — | ✓ (future) | ✓ (future) |
Tracker integration (remote/remote-state sync, tracker-backed boards) |
— | — | ✓ (future) |
Docs 06 and 07 are Pro-tier docs; every other doc applies to all tiers, with mode-conditioned passages (undo availability, popover git surface, the permanent-delete confirmation branch) resolving per the modes the tier ships. The free tier ships exactly one mode: none (with the inert-.git posture above); Pro ships the full state machine.
The target (re-ruled 2026-07-30)
One app target. The 2026-07-27 target split retires wholesale: the KanbanPro target, scheme, bundle id, module-alias test arrangement, verify-editions.sh, and the edition-twin files (EditionAbout, EditionTypes — Info.plist-posture twins existed only because two bundles claimed different ownership) all come out; the UTI is exported once. libgit2 links into the one target when the git provider is built (pro-m1) — dormant code behind the entitlement gate, not a second binary. Entitlements: the current minimal set plus network-client (exercised only under Pro; Keychain needs no access group — groups exist for sharing across apps). The pro-m1/pro-m2 milestones are unchanged in content — the git HistoryProvider and remote sync, built behind the seam — they now compile into the one target and activate by subscription.
App-side state (re-ruled 2026-07-30)
One sandbox: the board registry and its Application Support peers (02-architecture.md ▸ Per-board app state) home in the app's ordinary sandbox container — the App Group is removed wholesale, superseding the 2026-07-29 group ruling. No group entitlement, no per-edition grant slots (one bookmark per record), no per-edition open-now flags (one flag), no cross-process freshness stamping (one process — macOS apps are single-instance), no "Also open in…" awareness line, no group-id provisioning risk. The clipboard staging store, template store, and scalar defaults follow the same collapse.
Tier naming in the free app (settled — ruled 2026-07-27, carried through the collapse)
Quiet signposts. The free tier presents as a complete app, not a demo: Pro is named in exactly three places — one line in the About box, the contextual popover line on .git boards (above), and the Settings Pro section where the subscription actually lives. Nothing on the welcome screen, nothing in banners. The iCloud/network-volume warning (07-sync-collab.md) is written for the free tier without a git recommendation — it warns on its own merits (eviction, silent forks) and recommends a local folder; no Pro pitch in a warning (a warning that sells reads as manufactured).
Open questions
None currently — the one-app collapse, subscription shape, entitlement semantics, App Group removal, and no-grandfathering were ruled 2026-07-30; the popover slot posture and quiet signposts carry from 2026-07-27.