Skip to content

Commit f65dc7e

Browse files
dionmcmclaude
andcommitted
docs: add openspec proposals for macOS release distribution
Add change proposals for code signing, release automation, Homebrew tap, Sparkle auto-updates, and website landing page. Update first-launch-welcome proposal and specs to use Mailman mailing list instead of in-app data collection. Update privacy-settings spec to remove registration controls. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d654a69 commit f65dc7e

14 files changed

Lines changed: 364 additions & 0 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-03-05
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Why
2+
3+
We want to know who our users are (not just how many), build a contact list of engaged users, and encourage GitHub stars for visibility. Rather than collecting personal data in-app (which creates GDPR and Privacy Act obligations), we leverage CSIRO's existing Mailman infrastructure to offer an opt-in mailing list. This keeps the app free of personal data while giving us a communication channel with users.
4+
5+
## What Changes
6+
7+
- Show a first-launch welcome screen on first launch (or upgrade for existing users who haven't seen it)
8+
- Invite users to star the project on GitHub
9+
- Invite users to join the Codeagogo mailing list via a button that opens the Mailman subscription page in their browser
10+
- Add a "Show Welcome Screen" control to the Privacy section in Settings
11+
- Update PRIVACY.md to mention the mailing list (no personal data is collected by the app)
12+
13+
## Capabilities
14+
15+
### New Capabilities
16+
- `first-launch-welcome`: One-time welcome screen shown on first launch (or upgrade if not previously shown). Invites GitHub star and mailing list subscription via external Mailman page. The app never collects, stores, or transmits personal data. Never linked to anonymous usage metrics.
17+
18+
### Modified Capabilities
19+
- `privacy-settings`: Add "Show Welcome Screen" button to the existing Privacy section (added by the `anonymous-install-metrics` change). Registration status and "Clear Registration" are no longer needed since the app stores no personal data.
20+
21+
## Impact
22+
23+
- **AppDelegate.swift**: Welcome screen trigger added to launch sequence
24+
- **SettingsView.swift**: "Show Welcome Screen" button added to Privacy GroupBox
25+
- **PRIVACY.md**: Updated to mention mailing list link (no personal data collected by app)
26+
- **CHANGELOG.md**: New entry
27+
- **New files**: `WelcomeSettings.swift`, `WelcomeView.swift`, plus test files
28+
- **No breaking changes**
29+
- **No new dependencies**
30+
31+
## Design Decisions
32+
33+
1. **Mailman over in-app collection**: CSIRO runs Mailman-managed lists (e.g. ontoserver-announce) that are one-way, opt-in, user-managed, and IM&T-supported. Using Mailman means:
34+
- The app collects zero personal data (near-zero privacy compliance burden)
35+
- Double opt-in consent via Mailman's confirmation email (GDPR gold standard)
36+
- Users can self-manage subscription (subscribe/unsubscribe without our involvement)
37+
- Infrastructure is maintained by CSIRO IM&T, not us
38+
- Well-understood social contract ("join our mailing list")
39+
40+
2. **No personal data in the app**: Since the app just opens a URL, there are no name/email fields, no UserDefaults storage of personal info, no "Clear Registration" button needed, and no data breach notification obligations for the app.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-03-06
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Why
2+
3+
Homebrew is the dominant package manager on macOS. A Homebrew tap lets users install and update Codeagogo with a single command, which is the expected experience for developer and clinical informatician audiences.
4+
5+
## What Changes
6+
7+
- Add a Homebrew Cask formula at `Casks/codeagogo.rb` in this repository
8+
- Formula points to the signed `.dmg` on GitHub Releases
9+
- Document the installation instructions in README and on the website
10+
11+
## Capabilities
12+
13+
### New Capabilities
14+
- `homebrew-tap`: Homebrew Cask formula in the existing repository, enabling `brew tap aehrc/codeagogo https://github.com/aehrc/codeagogo && brew install --cask codeagogo`. Formula references the GitHub Releases download URL and SHA256 hash of the signed `.dmg`.
15+
16+
### Modified Capabilities
17+
<!-- None -->
18+
19+
## Impact
20+
21+
- **New file**: `Casks/codeagogo.rb`
22+
- **README.md**: Updated with Homebrew installation instructions
23+
- **Release process**: Each release needs the Cask formula updated with new version and SHA256
24+
- **No new repositories** — formula lives in the existing mac app repo
25+
- **No code changes to Codeagogo itself**
26+
27+
## Prerequisites
28+
29+
- `macos-code-signing` change completed (signed `.dmg` available)
30+
- At least one GitHub Release published with the signed `.dmg`
31+
32+
## Open Questions
33+
34+
1. **Formula update automation**: Manually update the formula per release, or automate via GitHub Actions in the release workflow?
35+
2. **Submission to homebrew-cask main**: Worth doing once we have user numbers. Requires minimum notability — revisit after launch.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-03-06
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## Why
2+
3+
Unsigned macOS apps trigger Gatekeeper warnings ("this app can't be opened because it is from an unidentified developer"), which is a significant barrier to adoption — especially for a tool that requires Accessibility permissions. Developer ID signing plus Apple notarization removes this friction entirely.
4+
5+
## What Changes
6+
7+
- Update `package-zip.sh` (or replace with a new `release.sh`) to include Developer ID code signing, notarization via `notarytool`, and stapling
8+
- Add a `.dmg` packaging step (drag-to-Applications disk image) as the primary distribution format
9+
- Document the signing prerequisites and release process
10+
- Add entitlements file if not already present (Accessibility, Hardened Runtime)
11+
12+
## Capabilities
13+
14+
### New Capabilities
15+
- `macos-code-signing`: Build script that signs the app with a Developer ID certificate, submits to Apple for notarization, waits for approval, and staples the notarization ticket to the binary. Produces a signed, notarized `.dmg` ready for distribution.
16+
17+
### Modified Capabilities
18+
<!-- None -->
19+
20+
## Impact
21+
22+
- **package-zip.sh**: Replaced or extended with signing/notarization steps
23+
- **Codeagogo.entitlements**: May need updates for Hardened Runtime compatibility
24+
- **New files**: `release.sh` (or equivalent), release documentation
25+
- **No code changes** — this is build/packaging only
26+
- **No new dependencies** (uses Xcode command-line tools)
27+
28+
## Prerequisites
29+
30+
- Apple Developer Program team seat (via CSIRO Publications)
31+
- Developer ID Application certificate installed in keychain
32+
- App-specific password or API key for `notarytool`
33+
- Team ID for notarization submission
34+
35+
## Open Questions
36+
37+
1. **Certificate access**: Will we use a shared team certificate or an individual one? Affects CI/CD setup.
38+
2. **DMG vs ZIP**: DMG with drag-to-Applications is more polished; ZIP is simpler. Recommend DMG.
39+
3. **Entitlements**: Need to verify Hardened Runtime compatibility with Accessibility APIs and Carbon hotkeys.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-03-06
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
## Why
2+
3+
Manual release processes are error-prone and slow. A GitHub Actions workflow that builds, signs, packages, and publishes macOS releases ensures consistent, reproducible releases and removes the bus factor of needing a specific person's machine.
4+
5+
## What Changes
6+
7+
- Add a GitHub Actions workflow triggered by version tags (e.g. `v1.0.0`)
8+
- Build, sign with Developer ID, notarize, staple, package as `.dmg`
9+
- Create a GitHub Release with the `.dmg` attached and auto-generated release notes
10+
- Update Homebrew tap formula (if automated)
11+
12+
## Capabilities
13+
14+
### New Capabilities
15+
- `release-automation`: GitHub Actions workflow that produces a signed, notarized macOS `.dmg` from a version tag push. Creates a GitHub Release with the artifact attached.
16+
17+
### Modified Capabilities
18+
<!-- None -->
19+
20+
## Impact
21+
22+
- **New files**: `.github/workflows/release.yml`, release documentation
23+
- **Secrets required**: Apple Developer ID cert + password, Apple API key for notarytool
24+
- **No code changes** — CI/CD only
25+
- **No new dependencies**
26+
27+
## Prerequisites
28+
29+
- `macos-code-signing` change completed (signing script exists to call)
30+
- GitHub repo secrets configured for signing certificate
31+
- Apple signing credentials available in CI
32+
33+
## Open Questions
34+
35+
1. **Self-hosted vs GitHub runners**: macOS signing may need a self-hosted runner if the certificate can't be installed in CI. GitHub-hosted macOS runners work but are slower and more expensive for private repos.
36+
2. **Release notes**: Auto-generate from CHANGELOG.md or write manually per release?
37+
3. **Depends on open/closed source decision**: Free CI/CD minutes for public repos; limited for private.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-03-06
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
## Why
2+
3+
Without auto-updates, users must manually check GitHub for new versions. Sparkle is the de facto standard framework for macOS app updates outside the App Store — used by Firefox, VLC, iTerm2, and hundreds of other apps. It handles checking for updates, downloading, verifying signatures, and installing — all in-app with no browser required. Auto-update should be enabled by default so users always have the latest version.
4+
5+
## What Changes
6+
7+
- Integrate the Sparkle 2.x framework via Swift Package Manager
8+
- Host an appcast XML file (version feed) on the website or in the repo
9+
- Sign updates with an Ed25519 key for integrity verification
10+
- Add "Check for Updates" menu item and auto-check on launch (enabled by default)
11+
- Add update preferences to Settings (auto-check on/off, check now button)
12+
- Update the release process to generate appcast entries and sign update archives
13+
14+
## Capabilities
15+
16+
### New Capabilities
17+
- `sparkle-updates`: In-app update mechanism using the Sparkle framework. Checks an appcast feed for new versions. Downloads, verifies (Ed25519 signature), and installs updates in-place. Auto-check is enabled by default. Users can check manually via menu item or disable automatic checks in Settings.
18+
19+
### Modified Capabilities
20+
- `privacy-settings`: Add update check preferences (auto-check on/off, check now button) to the Settings view.
21+
22+
## Impact
23+
24+
- **AppDelegate.swift**: Initialize Sparkle updater, add "Check for Updates" menu item
25+
- **SettingsView.swift**: Add update preferences section
26+
- **Info.plist**: Add Sparkle configuration keys (feed URL, public key)
27+
- **Release process**: Generate and sign appcast entries using `generate_appcast` tool
28+
- **New dependency**: Sparkle 2.x framework (via Swift Package Manager) — MIT licence, open source
29+
- **CHANGELOG.md**: New entry
30+
31+
## How Sparkle Works
32+
33+
1. App checks the appcast URL on a schedule (default: daily, configurable)
34+
2. Appcast lists versions with download URLs, Ed25519 signatures, and release notes
35+
3. If a newer version exists, Sparkle shows an update dialog with release notes
36+
4. User clicks "Install Update" — Sparkle downloads the archive, verifies the signature, replaces the app, and relaunches
37+
5. No browser, no manual download, no drag-to-Applications
38+
39+
## Prerequisites
40+
41+
- `macos-code-signing` change completed (signed builds required for updates)
42+
- Appcast hosting decided (website or repo — see `website-landing-page` change)
43+
- Ed25519 key pair generated for update signing (separate from Apple code signing)
44+
45+
## Notes
46+
47+
- This is the first external dependency in the project. Sparkle is MIT-licenced, widely used, and actively maintained. The alternative (rolling our own update checker) would be significantly more work for a worse result.
48+
- Auto-check is enabled by default with a daily interval. Users can disable it in Settings.
49+
50+
## Open Questions
51+
52+
1. **Appcast hosting**: On the website (alongside the landing page) or committed to the repo (served via GitHub raw URL)?
53+
2. **Appcast generation**: Automate with `generate_appcast` tool (ships with Sparkle) in the release workflow, or maintain manually? Recommend automating.
54+
3. **Delta updates**: Sparkle supports binary diffs (smaller downloads). Worth enabling or overkill for a small app?

0 commit comments

Comments
 (0)