Commit 30150d90cb

30150d90cbf30b2d3af720a730752ea6d3136117

parent: 302a2d2e7e

Unsigned

cmc <hello@cleberg.net> · 2026-07-16 05:03 UTC

chore: bump to 3.8.0 and record Phase 3 API features

MARKETING_VERSION 3.7.0 -> 3.8.0, build 89 -> 90.

SCOPE.md gains the items that did not survive contact with the API: archiveMessage
and mailingListSubscribe are blocked, while webhooks, shareSecret, and build
groups are reachable but declined on judgement. The reasoning is recorded so
they do not get re-proposed as gaps.

ROADMAP.md notes that Phase 3 is several releases rather than one, with the
measured size of each.

Layout: unified · split

Hutch.xcodeproj/project.pbxproj +12 −12
@@ -597,7 +597,7 @@
597597 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
598598 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
599599 CODE_SIGN_STYLE = Automatic;
600 CURRENT_PROJECT_VERSION = 89;
600 CURRENT_PROJECT_VERSION = 90;
601601 DEVELOPMENT_TEAM = ZCNAX3VL9D;
602602 ENABLE_PREVIEWS = YES;
603603 GENERATE_INFOPLIST_FILE = YES;
@@ -614,7 +614,7 @@
614614 "$(inherited)",
615615 "@executable_path/Frameworks",
616616 );
617 MARKETING_VERSION = 3.7.0;
617 MARKETING_VERSION = 3.8.0;
618618 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
619619 PRODUCT_NAME = "$(TARGET_NAME)";
620620 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -634,7 +634,7 @@
634634 ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
635635 CODE_SIGN_ENTITLEMENTS = Hutch/Hutch.entitlements;
636636 CODE_SIGN_STYLE = Automatic;
637 CURRENT_PROJECT_VERSION = 89;
637 CURRENT_PROJECT_VERSION = 90;
638638 DEVELOPMENT_TEAM = ZCNAX3VL9D;
639639 ENABLE_PREVIEWS = YES;
640640 GENERATE_INFOPLIST_FILE = YES;
@@ -651,7 +651,7 @@
651651 "$(inherited)",
652652 "@executable_path/Frameworks",
653653 );
654 MARKETING_VERSION = 3.7.0;
654 MARKETING_VERSION = 3.8.0;
655655 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch;
656656 PRODUCT_NAME = "$(TARGET_NAME)";
657657 STRING_CATALOG_GENERATE_SYMBOLS = YES;
@@ -714,7 +714,7 @@
714714 APPLICATION_EXTENSION_API_ONLY = YES;
715715 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
716716 CODE_SIGN_STYLE = Automatic;
717 CURRENT_PROJECT_VERSION = 89;
717 CURRENT_PROJECT_VERSION = 90;
718718 DEVELOPMENT_TEAM = ZCNAX3VL9D;
719719 GENERATE_INFOPLIST_FILE = NO;
720720 INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -724,7 +724,7 @@
724724 "@executable_path/Frameworks",
725725 "@executable_path/../../Frameworks",
726726 );
727 MARKETING_VERSION = 3.7.0;
727 MARKETING_VERSION = 3.8.0;
728728 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
729729 PRODUCT_NAME = "$(TARGET_NAME)";
730730 SKIP_INSTALL = YES;
@@ -743,7 +743,7 @@
743743 APPLICATION_EXTENSION_API_ONLY = YES;
744744 CODE_SIGN_ENTITLEMENTS = HutchWidgetExtension/HutchWidgetExtension.entitlements;
745745 CODE_SIGN_STYLE = Automatic;
746 CURRENT_PROJECT_VERSION = 89;
746 CURRENT_PROJECT_VERSION = 90;
747747 DEVELOPMENT_TEAM = ZCNAX3VL9D;
748748 GENERATE_INFOPLIST_FILE = NO;
749749 INFOPLIST_FILE = HutchWidgetExtension/Info.plist;
@@ -753,7 +753,7 @@
753753 "@executable_path/Frameworks",
754754 "@executable_path/../../Frameworks",
755755 );
756 MARKETING_VERSION = 3.7.0;
756 MARKETING_VERSION = 3.8.0;
757757 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchWidgetExtension;
758758 PRODUCT_NAME = "$(TARGET_NAME)";
759759 SKIP_INSTALL = YES;
@@ -772,7 +772,7 @@
772772 APPLICATION_EXTENSION_API_ONLY = YES;
773773 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
774774 CODE_SIGN_STYLE = Automatic;
775 CURRENT_PROJECT_VERSION = 89;
775 CURRENT_PROJECT_VERSION = 90;
776776 DEVELOPMENT_TEAM = ZCNAX3VL9D;
777777 GENERATE_INFOPLIST_FILE = NO;
778778 INFOPLIST_FILE = HutchSafariExtension/Info.plist;
@@ -782,7 +782,7 @@
782782 "@executable_path/Frameworks",
783783 "@executable_path/../../Frameworks",
784784 );
785 MARKETING_VERSION = 3.7.0;
785 MARKETING_VERSION = 3.8.0;
786786 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension;
787787 PRODUCT_NAME = "$(TARGET_NAME)";
788788 SKIP_INSTALL = YES;
@@ -801,7 +801,7 @@
801801 APPLICATION_EXTENSION_API_ONLY = YES;
802802 ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
803803 CODE_SIGN_STYLE = Automatic;
804 CURRENT_PROJECT_VERSION = 89;
804 CURRENT_PROJECT_VERSION = 90;
805805 DEVELOPMENT_TEAM = ZCNAX3VL9D;
806806 GENERATE_INFOPLIST_FILE = NO;
807807 INFOPLIST_FILE = HutchSafariExtension/Info.plist;
@@ -811,7 +811,7 @@
811811 "@executable_path/Frameworks",
812812 "@executable_path/../../Frameworks",
813813 );
814 MARKETING_VERSION = 3.7.0;
814 MARKETING_VERSION = 3.8.0;
815815 PRODUCT_BUNDLE_IDENTIFIER = net.cleberg.Hutch.HutchSafariExtension;
816816 PRODUCT_NAME = "$(TARGET_NAME)";
817817 SKIP_INSTALL = YES;
README.md +4 −1
@@ -14,13 +14,16 @@ The app currently includes:
1414- Home dashboard with assigned tickets, recent builds, and projects
1515- Repository browsing for Git and Mercurial repositories
1616- Repository details including README, references, commits, diffs, files, artifacts, and settings
17- Artifact upload and deletion on release tags
1718- Tracker and ticket browsing, ticket detail views, and tracker creation
1819- Ticket editing and deletion, with subscriptions for tickets and trackers
1920- Build job browsing, build detail views, and build submission
2021- Inbox and mailing list reading flows
2122- Patchset review: cover letters, per-patch diffs, checks, version chains, and status changes
23- Mailing list creation, settings, and deletion
24- Ticket activity feed across every tracker you follow
2225- Paste browsing, creation, and detail views
23- Profile and account settings, including SSH keys, PGP keys, and personal access token management
26- Profile and account settings, including SSH keys, PGP keys, personal access token management, and the audit log
2427- Email preferences for todo.sr.ht and lists.sr.ht
2528- Deep links for repositories, tickets, and build jobs
2629
ROADMAP.md +34 −16
@@ -131,22 +131,40 @@ GraphQL mutation. Treat that boundary as explicit rather than half-building it.
131131
132132## Phase 3: Polish and reach
133133
134- **Localization.** The project sets `LOCALIZATION_PREFERS_STRING_CATALOGS =
135 YES` but ships no string catalog, so every user-facing string is hardcoded
136 English.
137- **Accessibility.** Labels and hints appear in only 16 of roughly 130 view
138 files.
139- `uploadArtifact` / `deleteArtifact` — artifacts are read-only today.
140- Webhook management. Zero calls to any `create*Webhook` across every service.
141 Push notifications are out of scope because they need a relay server (see
142 [SCOPE.md](SCOPE.md)), but webhook management is client-side only and is a
143 prerequisite if that relay ever ships.
144- `auditLog` (meta.sr.ht) — unused security surface.
145- Build groups (`createGroup`, `startGroup`) and secret management
146 (`shareSecret`, the `secrets` query). Today `secrets` is only a submit toggle.
147- Mailing list creation and settings (`createMailingList`, `updateMailingList`,
148 `deleteMailingList`).
149- `events` feed (todo.sr.ht) and `archiveMessage` (lists.sr.ht).
134Unlike Phases 1 and 2, this is not one shippable thing. It is several, and they
135are sized very differently — measure before committing to one.
136
137### API features — done (v3.8.0)
138
139- ~~`uploadArtifact` / `deleteArtifact`~~ — artifacts were read-only.
140- ~~`auditLog` (meta.sr.ht)~~ — surfaced under the tokens in Profile.
141- ~~Mailing list creation and settings~~ (`createMailingList`,
142 `updateMailingList`, `deleteMailingList`).
143- ~~`events` feed (todo.sr.ht)~~ — a ticket activity feed under More.
144
145Four of the six planned. The other two did not survive contact:
146
147- `archiveMessage` is `@internal` and inaccessible.
148- Webhook management, `shareSecret`, and build groups are reachable but declined
149 on judgement — see [SCOPE.md](SCOPE.md) for the reasoning, so they do not get
150 re-proposed.
151
152### Localization
153
154The project sets `LOCALIZATION_PREFERS_STRING_CATALOGS = YES` but ships no
155string catalog, so every user-facing string is hardcoded English. Roughly 634
156literals: 239 `Text(`, 150 `Label(`, 117 `Button(`, 77 `Section(`, 51
157`navigationTitle(`.
158
159Worth knowing before starting: a catalog containing only English changes nothing
160for users until translations exist. It is groundwork, and it is the largest diff
161in the roadmap — it touches nearly every view, with the regression risk that
162implies.
163
164### Accessibility
165
166Labels and hints appear in 17 of 89 view files. Mechanical and low-risk, but it
167cannot be verified from a build — it needs VoiceOver driven on a device.
150168
151169### Swift 6 language mode
152170
SCOPE.md +21
@@ -7,3 +7,24 @@
77- Explore / search (hub.sr.ht) (no public discovery API)
88- Pronouns on profile (not in GraphQL schema)
99- Revoke personal access tokens (`@internal` in schema, inaccessible)
10- Archive a message to a list (`archiveMessage` is `@internal`, inaccessible)
11- Subscribe to a mailing list (`mailingListSubscribe` exists, but `MailingList`
12 has no `subscription` field and sr.ht has no discovery API, so there is no way
13 to find a list you are not already subscribed to — see hub.sr.ht above)
14- Submitting patches (a `git send-email` flow, not a GraphQL mutation; Hutch
15 reviews patchsets but cannot send them)
16
17## Declined rather than blocked
18
19These are reachable in the API. They are left out on judgement, not capability.
20
21- **Webhook management** (24 fields across five services). A webhook needs an
22 HTTPS endpoint you control to receive POSTs. Without the relay above, this
23 only serves someone already running their own endpoint, and that person is not
24 managing it from a phone. Reconsider if `hutch-notify` ever ships.
25- **`shareSecret`.** Shares a build secret — an SSH key or PAT — with another
26 user. A mistap grants someone else a credential, and nothing in the app can
27 take it back. That belongs on the web behind a full-size confirmation. The
28 read-only `secrets` list would be fine on its own.
29- **Build groups** (`createGroup`, `startGroup`). Multi-job pipelines are
30 authored in `.build.yml`, not composed on a phone.