Skip to main content

max / goingson

iOS TestFlight v0.3.1 ship + mobile cfg gating - Gate notifications module on non-mobile targets in email_sync_scheduler (Xcode build phase was failing silently due to unconditional desktop import) - Privacy policy draft (local-first, no telemetry, opt-in SyncKit disclosed) - Sync CFBundle versions to 0.3.1 - Document iOS pipeline in docs/deploy.md (App Manager API key requirement, altool key location quirk, mobile cfg gating, release-ios.sh find pitfall) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Author: Max J. <87768334+MaxJMath@users.noreply.github.com> · 2026-05-13 03:17 UTC
Commit: 94b4d6755d4d9dd14915326863e498db026da2ac
Parent: 722a07d
6 files changed, +91 insertions, -10 deletions
@@ -34,6 +34,21 @@ scp me@windows-x86:"C:/Users/me/Code/Apps/goingson/target/release/bundle/msi/*.m
34 34 scp me@windows-x86:"C:/Users/me/Code/Apps/goingson/target/release/bundle/nsis/*-setup.exe" ~/Dist/goingson/windows/
35 35 ```
36 36
37 + ## iOS / TestFlight
38 +
39 + ```bash
40 + ./dist/release-ios.sh # build + export + upload
41 + ./dist/release-ios.sh --build-only # archive only
42 + ./dist/release-ios.sh --upload-only # export + upload existing archive
43 + ```
44 +
45 + Requirements:
46 + - App Store Connect API key role must be **App Manager** or **Admin**. Developer-role keys fail at export with `Cloud signing permission error` / `No profiles for 'com.goingson.app' were found`. Roles are not editable — revoke and reissue.
47 + - `xcrun altool` looks for the `.p8` only in `~/.appstoreconnect/private_keys/`, `~/private_keys/`, `~/.private_keys/`, or `<cwd>/private_keys/`. The `--apiKeyPath` flag is not honored. Symlink: `ln -s /Users/max/Code/_private/AuthKey_<KEYID>.p8 ~/.appstoreconnect/private_keys/`.
48 + - Mobile-only target gating: any `use crate::notifications::...` or other desktop-only module imports must be `#[cfg(not(any(target_os = "ios", target_os = "android")))]`, matching the gate in `src-tauri/src/lib.rs`. The Rust compile is invoked from an Xcode build phase, so import errors fail the iOS build silently from Xcode's perspective.
49 +
50 + Current key: `35BZ6XF6GT` (App Manager). Team `93C54W92UP`. Bundle ID `com.goingson.app`. App Store Connect Apple ID `6759975645`.
51 +
37 52 ## Project-Specific Notes
38 53
39 54 - `beforeBuildCommand` uses `node src-tauri/frontend/build-css.js` (cross-platform).
@@ -0,0 +1,49 @@
1 + # GoingsOn — Privacy Policy
2 +
3 + *Last updated: May 12, 2026*
4 +
5 + GoingsOn is published by Make Creative, LLC. This policy explains what data the app handles.
6 +
7 + ## The Short Version
8 +
9 + - GoingsOn is a local-first app. Your tasks, emails, calendar events, and contacts live in a SQLite database on your own device.
10 + - We don't run a server for GoingsOn. We don't see your data.
11 + - If you opt in to cloud sync via SyncKit, your encrypted data is replicated to a server you choose; in that case the operator's privacy policy applies.
12 + - No telemetry, analytics, ads, or tracking.
13 +
14 + ## What GoingsOn Stores on Your Device
15 +
16 + - Tasks, projects, notes, calendar events, contacts
17 + - Email account credentials (IMAP/SMTP passwords, OAuth tokens) — stored in the OS keychain, never written to plain disk
18 + - Cached email message bodies and metadata for accounts you've added
19 + - Plugin scripts you install
20 +
21 + This data stays on your device unless you choose to sync it.
22 +
23 + ## What GoingsOn Sends Off Your Device
24 +
25 + GoingsOn connects directly to services *you* configure:
26 +
27 + - **Email servers** (IMAP/SMTP/JMAP) you add — Google, Microsoft, Fastmail, or any other host. We don't proxy these connections; they go straight from your device.
28 + - **OAuth providers** (Google, Microsoft, Fastmail) when you authenticate an email account. The OAuth tokens are issued by those providers under their own privacy policies.
29 + - **Update server** — the app periodically checks for new versions. The check transmits your current app version and platform; no personal data.
30 + - **SyncKit sync** (optional, off by default) — if you enable it, the app talks to a SyncKit-compatible server using end-to-end encrypted payloads.
31 +
32 + ## What GoingsOn Does Not Do
33 +
34 + - No analytics SDK, no crash reporter beacons, no usage tracking
35 + - No advertising, no third-party trackers
36 + - No location collection
37 + - No data sold or shared with third parties
38 +
39 + ## Children
40 +
41 + GoingsOn is not directed at children under 13.
42 +
43 + ## Changes
44 +
45 + Material changes to this policy will be noted in the app's release notes.
46 +
47 + ## Contact
48 +
49 + questions@makenot.work
@@ -35,12 +35,27 @@ Done: Phases 1-7 (CSS, touch, navigation, views, build config, tab bar, distribu
35 35 ./dist/release-ios.sh --build-only # build archive only
36 36 ./dist/release-ios.sh --upload-only # export + upload existing archive
37 37 ```
38 - - [ ] Accept PLA at developer.apple.com/account
38 + - [x] Accept PLA at developer.apple.com/account
39 39 - [x] Register App ID for `com.goingson.app` (Certificates, Identifiers & Profiles)
40 - - [ ] App Store Connect: create app record (name: GoingsOn, SKU: goingson)
41 - - [ ] Upload to TestFlight via `dist/release-ios.sh`
42 - - [ ] Add beta testers
43 - - [ ] Physical device testing before sending TestFlight invites
40 + - [x] App Store Connect: create app record (bundle `com.goingson.app`, SKU `goingson-1`, Apple ID `6759975645`)
41 + - [x] Upload v0.3.1 to TestFlight via `dist/release-ios.sh` (2026-05-12)
42 + - [x] v0.3.1 build processed (status: VALID)
43 + - [x] Answer encryption export-compliance prompt — set via API to `usesNonExemptEncryption: false` (exempt; standard HTTPS/system crypto)
44 +
45 + #### Internal testing (immediate, for own device)
46 + - [ ] App Store Connect → Users and Access → invite phone's Apple ID (role: Developer)
47 + - [ ] Accept invitation from phone's Apple ID
48 + - [ ] TestFlight → Internal Testing → "+" group → add phone Apple ID → add build
49 + - [ ] Install TestFlight on phone, accept invite, install build, smoke-test
50 +
51 + #### External testing (public link, slower first time)
52 + - [x] Privacy policy drafted at `docs/privacy-policy.md`
53 + - [ ] Add Privacy Policy page to GoingsOn project on MNW (dashboard → Settings → Pages); URL will be `https://makenot.work/p/goingson#section-privacy-policy`. Pages feature shipped in MNW v0.5.17.
54 + - [ ] TestFlight → External Testing → "+" group → add v0.3.1 build
55 + - [ ] Fill in Beta App Information: description, feedback email, test notes ("no login required for core features")
56 + - [ ] Submit for Beta App Review (first time: ~24-48h; subsequent builds: minutes via automated screening)
57 + - [ ] Once approved, enable Public Link
58 + - [ ] Push at least one build per quarter — TestFlight builds expire after 90 days
44 59
45 60 ### Android
46 61 ```bash
@@ -15,9 +15,9 @@
15 15 <key>CFBundlePackageType</key>
16 16 <string>APPL</string>
17 17 <key>CFBundleShortVersionString</key>
18 - <string>0.3.0</string>
18 + <string>0.3.1</string>
19 19 <key>CFBundleVersion</key>
20 - <string>0.3.0</string>
20 + <string>0.3.1</string>
21 21 <key>LSRequiresIPhoneOS</key>
22 22 <true/>
23 23 <key>UILaunchStoryboardName</key>
@@ -52,8 +52,8 @@ targets:
52 52 - UIInterfaceOrientationPortraitUpsideDown
53 53 - UIInterfaceOrientationLandscapeLeft
54 54 - UIInterfaceOrientationLandscapeRight
55 - CFBundleShortVersionString: 0.3.0
56 - CFBundleVersion: "0.3.0"
55 + CFBundleShortVersionString: 0.3.1
56 + CFBundleVersion: "0.3.1"
57 57 entitlements:
58 58 path: goingson-desktop_iOS/goingson-desktop_iOS.entitlements
59 59 scheme:
@@ -11,6 +11,7 @@ use tokio_util::sync::CancellationToken;
11 11 use tracing::{debug, error, info, warn};
12 12
13 13 use crate::commands::sync_email_account_inner;
14 + #[cfg(not(any(target_os = "ios", target_os = "android")))]
14 15 use crate::notifications::send_notification;
15 16 use crate::state::AppState;
16 17
@@ -127,7 +128,8 @@ async fn check_and_sync_accounts(
127 128 result.archive_fetched
128 129 );
129 130
130 - // Send notification if enabled and new emails arrived
131 + // Send notification if enabled and new emails arrived (desktop only)
132 + #[cfg(not(any(target_os = "ios", target_os = "android")))]
131 133 if account.notify_new_emails && result.emails_saved > 0 {
132 134 let body = if result.emails_saved == 1 {
133 135 format!("1 new email in {}", account.account_name)