Collapse the edition split — one target, twins merged, verify-editions retired

Phase 1 of the 2026-07-30 one-app pivot (DESIGN 0bec9a6, card c3a3ddd5):
the KanbanPro target, LaneworkPro scheme, KanbanProTests module-alias
bundle, KanbanPro/ source root and scripts/verify-editions.sh retire
wholesale. project.yml reads as a single-target file again (anchors
inlined, header rewritten in tier vocabulary).

The edition twins merge: EditionTypes -> PasteboardTypes (one
UTType(exportedAs:) home — the one app owns the family types),
EditionAbout -> AboutBox (the quiet Pro signpost survives as the About
box's one line; "…in Settings" deferred until the StoreKit phase gives
it somewhere to point). InertGitTests drops its Base prefix — the
inert-.git posture is unconditional app behavior, unsubscribed and
lapsed being one state.

Entitlements gain com.apple.security.network.client, declared now and
dormant until Pro's remotes use it; no keychain access group. The App
Group key deliberately stays — it goes with AppGroup.swift in phase 2,
since pulling it first would silently drop the app into the fallback
container. README/RELEASE.md build-and-pipeline prose updated to the
one-record world; the subscription story lands with phase 3.

1893 tests in 322 suites green.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-30 17:25:50 -04:00
parent f7c8088783
commit 092300c7d2
52 changed files with 253 additions and 905 deletions
+15 -16
View File
@@ -4,11 +4,11 @@
**Lanework ships on the Mac App Store**, as version 2.0 of the existing `dev.rzen.indie.Kanban` App Store record — the 1.x app already listed there under the name Lanework. This was not an open question by the time this document was written; three prior rulings settle it:
- The 2026-07-27 edition split (DESIGN/12-editions.md) defines the editions as **separate App Store targets** and gave base Lanework the existing `dev.rzen.indie.Kanban` bundle id precisely so it ships as the update to the existing record; Lanework Pro (`dev.rzen.indie.KanbanPro`) becomes its own record when it ships after pro-m1/pro-m2.
- The one-app collapse (DESIGN/12-editions.md, re-ruled 2026-07-30, superseding the 2026-07-27 two-app split) puts the whole family on **one record**: `dev.rzen.indie.Kanban`, the id 1.x already ships under, so 2.0 is simply its update. Lanework Pro arrives inside it as a subscription after pro-m1/pro-m2, never as a second record.
- The marketing version has been 2.0 since m3 — the successor numbering of the shipped 1.x.
- The portfolio's whole release tooling (appstore-publish skill, `asc-*.swift` scripts, the account's API key) is App-Store-shaped, and the 1.x pipeline for this very record already exists and works.
Notarized direct distribution is deliberately **not** pursued for 2.0: a second channel means a second update path and a second set of listing assets for no current audience, and nothing in the app requires escaping the App Store's sandbox rules (the app is already sandboxed with user-selected file access; base has no network entitlement at all). Revisit only if App Review rejects something architectural.
Notarized direct distribution is deliberately **not** pursued for 2.0: a second channel means a second update path and a second set of listing assets for no current audience, and nothing in the app requires escaping the App Store's sandbox rules (the app is already sandboxed with user-selected file access, and its network-client entitlement stays dormant until Pro's remotes use it). Revisit only if App Review rejects something architectural.
## The pipeline
@@ -29,20 +29,19 @@ set -a; source .env.release; set +a; swift ../indie-skills/skills/appstore-publi
Run top to bottom; nothing below "PUSH POINT" may run without a deliberate decision — every step after it writes to the live App Store record of a shipping 1.x app.
1. [ ] All milestone work committed and pushed (build number = commit count).
2. [ ] Both unit suites green: `xcodebuild test … -scheme Kanban` and `… -scheme LaneworkPro` (`-only-testing:KanbanTests` / `KanbanProTests`).
3. [ ] `scripts/verify-editions.sh` — 26/26.
4. [ ] UI test pass on a real display (KanbanUITests: accessibility audits + end-to-end golden flows), plus the manual checklists (`KanbanUITests/AccessibilityVerification.md`, toolbar/undo/trash/drag-preview lists).
5. [ ] CHANGELOG.md current (it is the in-app release notes) — What's New (`scripts/metadata/version/en-US/whats_new.txt`) tells the same story.
6. [ ] Screenshots: capture the 2.0 board on a real display (APP_DESKTOP sizes come straight from screenshots of the running app; numeric filename prefixes set the store order).
7. [ ] Archive dry run: `scripts/release.sh` at least through the archive step completes locally.
8. **— PUSH POINT (everything below touches the live record) —**
9. [ ] `scripts/release.sh` — archive + upload the build.
10. [ ] Metadata dry run, then push (`asc-metadata.swift --platform macos`, commands above).
11. [ ] Verify pricing (currently free, carried from 1.x) and availability (ALL territories) still match intent — Pro will be the paid tier later.
12. [ ] Stage: `asc-submit.swift --bundle dev.rzen.indie.Kanban --version 2.0 --platform macos` (waits for build processing, attaches, stages the review submission — does not submit).
13. [ ] Review the staged listing at appstoreconnect.apple.com (age rating, privacy labels, and content rights carry over from 1.x — the stage step's errors will name anything missing).
14. [ ] Submit: the same command with `--submit`.
2. [ ] Unit suite green: `xcodebuild test -project Kanban.xcodeproj -scheme Kanban -destination 'platform=macOS,arch=arm64' -only-testing:KanbanTests`.
3. [ ] UI test pass on a real display (KanbanUITests: accessibility audits + end-to-end golden flows), plus the manual checklists (`KanbanUITests/AccessibilityVerification.md`, toolbar/undo/trash/drag-preview lists).
4. [ ] CHANGELOG.md current (it is the in-app release notes) — What's New (`scripts/metadata/version/en-US/whats_new.txt`) tells the same story.
5. [ ] Screenshots: capture the 2.0 board on a real display (APP_DESKTOP sizes come straight from screenshots of the running app; numeric filename prefixes set the store order).
6. [ ] Archive dry run: `scripts/release.sh` at least through the archive step completes locally.
7. **— PUSH POINT (everything below touches the live record) —**
8. [ ] `scripts/release.sh` — archive + upload the build.
9. [ ] Metadata dry run, then push (`asc-metadata.swift --platform macos`, commands above).
10. [ ] Verify pricing (currently free, carried from 1.x) and availability (ALL territories) still match intent — Pro will be the paid tier later.
11. [ ] Stage: `asc-submit.swift --bundle dev.rzen.indie.Kanban --version 2.0 --platform macos` (waits for build processing, attaches, stages the review submission — does not submit).
12. [ ] Review the staged listing at appstoreconnect.apple.com (age rating, privacy labels, and content rights carry over from 1.x — the stage step's errors will name anything missing).
13. [ ] Submit: the same command with `--submit`.
## Lanework Pro (later)
Pro ships after pro-m1 (git history) and pro-m2 (remote sync) as a **new** App Store record: bundle id `dev.rzen.indie.KanbanPro`, its own metadata folder and pricing (paid), created by hand in App Store Connect first (the API cannot create app records). The `scripts/release.sh` config block parameterizes to the `LaneworkPro` scheme at that point; everything else in the pipeline is shared.
Pro is **a subscription inside this app, not a second record** (DESIGN/12-editions.md ▸ Distribution, re-ruled 2026-07-30): the two-app split that once wanted its own bundle id, metadata folder and scheme here is retired. It ships after pro-m1 (git history) and pro-m2 (remote sync) as an auto-renewable subscription configured against `dev.rzen.indie.Kanban` in App Store Connect. Nothing in this pipeline changes for it — same scheme, same archive, same upload; the subscription products and their review materials are the added work, and this section gets its steps when that phase is designed.