Files
lanework/project.yml
T
rzen 2c6b8fe63a Remove the App Group wholesale — one sandbox, one bookmark, one flag
Phase 2 of the one-app pivot (DESIGN 12 ▸ App-side state, re-ruled
2026-07-30; reworks 566deab). AppGroup retires; what remains is
AppStateHome — ordinary sandbox Application Support as the one home for
the registry, clipboard staging and template stores, keeping the
unit-test-host redirect (the test host is the app and would sweep real
state). Scalar defaults return to UserDefaults.standard.

BoardRecord's per-edition grant slots and openNow flags collapse to one
bookmark + one isOpenNow; the legacy-key decode and adopt-in-memory
paths go (nothing shipped with group-era records), while the founding
four-keys-required / defaults-for-everything-since decode policy stays —
a bookmarkless record decodes as the born-orphan row rather than
quarantining the list. needsReopen and the pre-anchored re-grant panel
are removed whole: the only state that flow served — a record granted by
a sibling sandbox — is unrepresentable now, and a dead bookmark of our
own was already the orphan case by explicit comment. The
indexOfRecord path fallback dies with it; path is never a key again.

The cross-process freshness stamp (mtime+size re-read) and
BoardEditionPresence with its popover "Also open in…" line retire; the
clipboard prune keeps its atomic .sweeping/ claim-then-delete, reframed
for crash residue and open -n copies rather than sibling editions. The
application-groups entitlement key is gone.

1880 tests in 317 suites green (13 cross-edition tests retired with
their subject).

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
2026-07-30 17:46:32 -04:00

175 lines
6.9 KiB
YAML

name: Kanban
options:
bundleIdPrefix: dev.rzen.indie
deploymentTarget:
macOS: "26.0"
xcodeVersion: "26.0"
defaultConfig: Debug
packages:
Yams:
url: https://github.com/jpsim/Yams.git
from: 6.0.0
# apple/swift-markdown — the card window's Preview parser (05-card-window.md ▸ Preview).
# Pinned to the next *minor* rather than the next major because the package is pre-1.0: a
# `from:` range here would silently accept 0.9's breaking changes, which is not what `from:`
# means for Yams at 6.x.
swift-markdown:
url: https://github.com/apple/swift-markdown.git
minorVersion: 0.8.0
# The About window: app icon, version/build from the stamped Info.plist, and the bundled
# LICENSE/CHANGELOG documents. Pre-1.0 like swift-markdown, same pinning logic.
IndieAbout:
url: https://git.rzen.dev/rzen/indie-about.git
minorVersion: 0.2.2
settings:
base:
SWIFT_VERSION: "6.0"
MACOSX_DEPLOYMENT_TARGET: "26.0"
DEVELOPMENT_TEAM: ${APPLE_TEAM_ID}
ENABLE_USER_SCRIPT_SANDBOXING: NO
# **One app target** (12-editions.md ▸ The target, re-ruled 2026-07-30). Lanework ships as a single
# Mac App Store app, `dev.rzen.indie.Kanban`; **Lanework Pro is a subscription inside it**, not a
# second binary. The 2026-07-27 two-target split — a `KanbanPro` application target, its scheme, its
# bundle id, the `-module-alias Kanban=KanbanPro` test bundle and the twin source files that existed
# only because two bundles claimed different UTI ownership — retired wholesale with the collapse.
#
# What that buys this file: no anchors, no per-target exclusion lists, no second copy of the
# resources. There is one product, one Info.plist, one entitlements file, one Swift module, and one
# `.kanban` UTI **exported** (never imported) by the app that owns it.
#
# libgit2 arrives here with pro-m1 — a dependency of the one target, dormant behind the subscription
# gate rather than the contents of a second download.
targets:
# MARK: - Lanework
Kanban:
type: application
platform: macOS
sources:
- Kanban
# The bundled template store (09-templates.md ▸ Definition format): real board folders,
# copied into `Contents/Resources/Templates/` verbatim as a folder reference — the same
# arrangement `Fixtures/` uses below, and for the same reason. A template is a board, so it
# must reach the bundle as directories on disk, not as flattened resource files.
- path: Templates
type: folder
buildPhase: resources
# The About window's documents (LICENSE, CHANGELOG) — bundled so IndieAbout can render
# them in-app. Apple-inline-Markdown subset only: no `#` headings, no hard-wrapped
# paragraphs (every newline renders literally).
- path: LICENSE.md
type: file
buildPhase: resources
- path: CHANGELOG.md
type: file
buildPhase: resources
dependencies:
- package: Yams
- package: swift-markdown
product: Markdown
- package: IndieAbout
postBuildScripts:
- script: '"${SRCROOT}/../indie-skills/skills/app-versioning/scripts/update_build_info.sh"'
name: Update Build Info
shell: /bin/sh
basedOnDependencyAnalysis: false
inputFiles:
- $(TARGET_BUILD_DIR)/$(INFOPLIST_PATH)
- $(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Info.plist
settings:
base:
# The identifier 1.x shipped under, unchanged: 2.0 updates that App Store record rather
# than opening a second one (12-editions.md ▸ Distribution, ruled 2026-07-30).
PRODUCT_BUNDLE_IDENTIFIER: dev.rzen.indie.Kanban
MARKETING_VERSION: "2.0"
INFOPLIST_FILE: Kanban/Info.plist
# `Kanban/Kanban.entitlements` — sandbox, user-selected files, app-scope bookmarks, and
# `com.apple.security.network.client`, which is **declared now and dormant until Pro
# ships**: the one binary carries the key, and nothing exercises it until the git
# provider's remotes do under an active subscription (12 ▸ The target). No App Group and
# no keychain access group — groups exist to share *between* apps, and there is one app,
# so app-side state homes in the ordinary sandbox container (`AppStateHome`).
CODE_SIGN_ENTITLEMENTS: Kanban/Kanban.entitlements
GENERATE_INFOPLIST_FILE: false
SWIFT_STRICT_CONCURRENCY: complete
ASSETCATALOG_COMPILER_APPICON_NAME: AppIcon
# MARK: - Unit tests
#
# The suite, hosted by the app: every test in `KanbanTests/` exercises the storage format, the
# live store or the UI model through `@testable import Kanban`, so it needs the app's module and
# its bundle around it. `Fixtures/` rides in as a folder reference for the same reason the
# templates do — a fixture is a board, and a board is directories on disk.
KanbanTests:
type: bundle.unit-test
platform: macOS
sources:
- KanbanTests
- path: Fixtures
type: folder
buildPhase: resources
dependencies:
- target: Kanban
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: dev.rzen.indie.KanbanTests
GENERATE_INFOPLIST_FILE: true
SWIFT_STRICT_CONCURRENCY: complete
# MARK: - UI tests
#
# These launch the real app and drive its menu bar — the slowest, most environment-dependent part
# of the suite. The accessibility audits (10-accessibility.md ▸ Verification) walk every surface
# the design names.
KanbanUITests:
type: bundle.ui-testing
platform: macOS
sources:
# The verification documents live with the tests they belong to (10-accessibility.md
# ▸ Verification: "A manual VoiceOver smoke script lives with the test plan"), so they are
# listed in the project — visible where the suite is — but with no build phase: they are
# documentation, not resources the bundle should carry. `EndToEndVerification.md` is the same
# arrangement for the golden-flow, fail-fast and performance suites: the run command, the
# prerequisites, and the flows that stayed manual.
- path: KanbanUITests
excludes:
- "**/*.md"
- path: KanbanUITests/AccessibilityVerification.md
buildPhase: none
- path: KanbanUITests/EndToEndVerification.md
buildPhase: none
dependencies:
- target: Kanban
settings:
base:
PRODUCT_BUNDLE_IDENTIFIER: dev.rzen.indie.KanbanUITests
GENERATE_INFOPLIST_FILE: true
SWIFT_STRICT_CONCURRENCY: complete
schemes:
# `xcodebuild … -scheme Kanban` is the established command for this repo, and it now means the
# only app there is.
Kanban:
build:
targets:
Kanban: all
run:
config: Debug
test:
config: Debug
gatherCoverageData: false
targets:
- KanbanTests
- KanbanUITests
profile:
config: Release
analyze:
config: Debug
archive:
config: Release