The pasteboard UTType constants become edition twins — Pro stops claiming ownership it doesn't have

Latent since the m7 split: base's Info.plist exports the three family
pasteboard types (cards, lanes, clipboard) and Pro's imports them, but
the shared constants declared all three UTType(exportedAs:) — a claim
of ownership the system checks against the running app's plist. In Pro
that claim is false, and the first touch (the clipboard type, via the
launch sweep) raised a runtime fault that blocked board loading under
the debugger.

EditionAbout's twin-file pattern, applied to an initializer: the
constants move to Kanban/App/EditionTypes.swift (exportedAs) with a
KanbanPro/Edition/EditionTypes.swift twin (importedAs, identifiers
verbatim); project.yml excludes base's copy from Pro. Type identity is
the string, so payloads cross editions unchanged. Verified: Pro
fixture launch opens the board with zero UTI warnings; both suites
green; verify-editions 30/30.

Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
2026-07-29 21:46:27 -04:00
parent 27158a06cd
commit 546ed94412
5 changed files with 67 additions and 21 deletions
+7 -9
View File
@@ -3,15 +3,13 @@ import Foundation
import UniformTypeIdentifiers
// MARK: - The clipboard type
extension UTType {
/// What a Lanework copy puts on the pasteboard under its own type the JSON `ClipboardManifest`
/// (04-interactions.md Clipboard: "the pasteboard carries a JSON manifest + plain text").
/// Declared as an exported type in `Info.plist` beside the two drag types, for the same reason
/// those are: a payload nobody has declared is a payload the system will not carry.
static let laneworkClipboard = UTType(exportedAs: "dev.rzen.indie.kanban.clipboard")
}
//
// `UTType.laneworkClipboard` what a Lanework copy puts on the pasteboard under its own type, the
// JSON `ClipboardManifest` below (04-interactions.md Clipboard: "the pasteboard carries a JSON
// manifest + plain text"). Declared in `Info.plist` beside the two drag types, for the same reason
// those are: a payload nobody has declared is a payload the system will not carry. The constant
// itself lives in `EditionTypes.swift` base exports the type, Pro imports it, and each edition's
// twin uses the initializer its own plist can honor.
// MARK: - The manifest