Commit d5dec7be8a
Unsigned
Layout: unified · split
ROADMAP.md +67 −8
| @@ -134,6 +134,28 @@ GraphQL mutation. Treat that boundary as explicit rather than half-building it. | ||
| 134 | 134 | Unlike Phases 1 and 2, this is not one shippable thing. It is several, and they |
| 135 | 135 | are sized very differently — measure before committing to one. |
| 136 | 136 | |
| 137 | ### Release plan | |
| 138 | ||
| 139 | Hutch is an app with a `MARKETING_VERSION`, not a library with an API contract, | |
| 140 | so "breaking change" does not apply. These buckets track *user-visible scale*. | |
| 141 | ||
| 142 | | Version | Contents | Why here | | |
| 143 | | --- | --- | --- | | |
| 144 | | v3.8.1 | SonarCloud triage; housekeeping | No behaviour change at all | | |
| 145 | | v3.9.0 | "What's cooking" ingest; doc truth-up; deploy keys | Ships one feature, corrects the map | | |
| 146 | | v3.10.0 | hub.sr.ht writes: projects, discovery, `mailingListSubscribe` | Provisional — gated on what v3.9.0 finds | | |
| 147 | | v3.11.0 | Accessibility | Independent, device-verified | | |
| 148 | | v4.0.0 | Localization *with* translations | The only true re-presentation | | |
| 149 | | — | Swift 6 language mode; cache reads | Internal; ride along, no tag | | |
| 150 | ||
| 151 | Ordering is by dependency, not size. v3.9.0 leads because it is the only item | |
| 152 | that corrects the others' inputs: the ingest's real output is a `SCOPE.md` that | |
| 153 | is true, and v3.10.0 rests entirely on one unverified sentence in a blog post. | |
| 154 | Do not commit v3.10.0's number until the SDL has been read — the bucket may turn | |
| 155 | out to be empty, which is the point of sequencing it second. | |
| 156 | ||
| 157 | `KeychainHelper` is deliberately unbucketed; see the SonarCloud hotspots below. | |
| 158 | ||
| 137 | 159 | ### API features — done (v3.8.0) |
| 138 | 160 | |
| 139 | 161 | - ~~`uploadArtifact` / `deleteArtifact`~~ — artifacts were read-only. |
| @@ -152,7 +174,7 @@ Three of the six planned. The other three did not survive contact: | ||
| 152 | 174 | on judgement — see [SCOPE.md](SCOPE.md) for the reasoning, so they do not get |
| 153 | 175 | re-proposed. |
| 154 | 176 | |
| 155 | ### Localization | |
| 177 | ### Localization — v4.0.0, and only with translations | |
| 156 | 178 | |
| 157 | 179 | The project sets `LOCALIZATION_PREFERS_STRING_CATALOGS = YES` but ships no |
| 158 | 180 | string catalog, so every user-facing string is hardcoded English. Roughly 634 |
| @@ -164,12 +186,19 @@ for users until translations exist. It is groundwork, and it is the largest diff | ||
| 164 | 186 | in the roadmap — it touches nearly every view, with the regression risk that |
| 165 | 187 | implies. |
| 166 | 188 | |
| 167 | ### Accessibility | |
| 189 | That combination is why this is bucketed at v4.0.0 *bundled with at least one | |
| 190 | real translation*, rather than shipped alone. An English-only catalog would earn | |
| 191 | the major number on regression risk while delivering nothing — the wrong trade. | |
| 192 | Hold the catalog until a translation lands. If it ever ships unbundled, it is | |
| 193 | groundwork and belongs in a quiet minor, not a 4.0. | |
| 194 | ||
| 195 | ### Accessibility — v3.11.0 | |
| 168 | 196 | |
| 169 | 197 | Labels and hints appear in 17 of 89 view files. Mechanical and low-risk, but it |
| 170 | 198 | cannot be verified from a build — it needs VoiceOver driven on a device. |
| 199 | Independent of every other bucket, so it can move if a device pass is convenient. | |
| 171 | 200 | |
| 172 | ### SonarCloud backlog | |
| 201 | ### SonarCloud backlog — v3.8.1 | |
| 173 | 202 | |
| 174 | 203 | 51 open issues: **0 bugs, 0 vulnerabilities, 51 code smells**, plus 3 security |
| 175 | 204 | hotspots. The headline number is misleading, so trust the breakdown before |
| @@ -193,7 +222,11 @@ The 3 hotspots are the part actually worth thought: | ||
| 193 | 222 | `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` with no |
| 194 | 223 | `SecAccessControl`, so it does not require biometric or passcode |
| 195 | 224 | authentication to read. That is a genuine product decision — should a stolen, |
| 196 | unlocked phone hand over a sr.ht token? — not a lint nit. | |
| 225 | unlocked phone hand over a sr.ht token? — not a lint nit. **Unbucketed on | |
| 226 | purpose:** adding `SecAccessControl` changes what a user must do to read their | |
| 227 | own token, so it needs a decision first. If the answer is yes, it is a minor | |
| 228 | bump of its own — a visible auth change should not hide inside a feature | |
| 229 | release. | |
| 197 | 230 | - `ReadmeView:1922` (**LOW**) — unrestricted WebView navigation. Probably a false |
| 198 | 231 | positive: `isAllowedReadmeNavigationURL` enforces a scheme allowlist. Verify, |
| 199 | 232 | then annotate. |
| @@ -201,7 +234,12 @@ The 3 hotspots are the part actually worth thought: | ||
| 201 | 234 | Query it with: |
| 202 | 235 | `https://sonarcloud.io/api/issues/search?componentKeys=zerolabsco_hutch&resolved=false` |
| 203 | 236 | |
| 204 | ### Ingest "What's cooking on SourceHut?" | |
| 237 | This is a patch because nothing executes differently afterwards. The 35 hardcoded-URI | |
| 238 | issues are resolved as *Won't Fix* in SonarCloud's web UI — not a commit at all — and | |
| 239 | the rest is three comments and one annotation. If it produces a diff that changes a | |
| 240 | runtime path, something has gone wrong. | |
| 241 | ||
| 242 | ### Ingest "What's cooking on SourceHut?" — v3.9.0 | |
| 205 | 243 | |
| 206 | 244 | sr.ht posts a quarterly update to `~sircmpwn/sr.ht-announce`, mirrored at |
| 207 | 245 | <https://sourcehut.org/blog/>. Nothing in Hutch tracks it, so the API grows and |
| @@ -227,7 +265,25 @@ flags two openings: | ||
| 227 | 265 | Start from Q1 2026 forward — that is roughly when the current `Docs/API` dumps |
| 228 | 266 | were captured. |
| 229 | 267 | |
| 230 | ### Swift 6 language mode | |
| 268 | Research does not ship, so v3.9.0 pairs the ingest with **deploy keys** — the one | |
| 269 | self-contained feature it has already surfaced and that the SDL confirms exists. | |
| 270 | That gives the release something a user can see. Everything else the ingest turns | |
| 271 | up gets filed, not built, and hub.sr.ht gets its own bucket below. | |
| 272 | ||
| 273 | ### hub.sr.ht writes — v3.10.0, provisional | |
| 274 | ||
| 275 | Everything here rests on a single sentence in the Q2 2026 post: that hub.sr.ht | |
| 276 | gained a writable GraphQL API. If true, three things unblock at once — | |
| 277 | project writes (Hutch's projects are read-only), discovery (which `SCOPE.md` | |
| 278 | rules out on the grounds hub has no public API), and `mailingListSubscribe`, | |
| 279 | which Phase 1 declined for exactly that reason. | |
| 280 | ||
| 281 | All three live or die on the same unverified claim, which is why this is | |
| 282 | sequenced after the ingest rather than planned now. Read | |
| 283 | `api/graph/schema.graphqls` in `hub.sr.ht` before committing the version number. | |
| 284 | The bucket may be empty. | |
| 285 | ||
| 286 | ### Swift 6 language mode — no release of its own | |
| 231 | 287 | |
| 232 | 288 | The project builds in Swift 5 language mode with |
| 233 | 289 | `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor`. Moving to Swift 6 is blocked on |
| @@ -243,14 +299,17 @@ concurrency diagnostics that are warnings today and errors there: | ||
| 243 | 299 | methods, as in `HomeViewModel.loadDashboard` and |
| 244 | 300 | `NotificationPreferencesViewModel.load`. |
| 245 | 301 | |
| 246 | ### Cache reads that bypass the client | |
| 302 | ### Cache reads that bypass the client — no release of its own | |
| 247 | 303 | |
| 248 | 304 | `BuildListViewModel`, `RepositoryListViewModel`, and `PasteService` still read |
| 249 | 305 | `client.responseCache` directly, each falling back across two different cache |
| 250 | 306 | keys. That predates `APICacheKeys` and should be folded into `cachedPayload`, |
| 251 | 307 | which already consults the persistent cache before the memory layer. |
| 252 | 308 | |
| 253 | ## Housekeeping | |
| 309 | Like Swift 6 above, this is internal and rides along with whatever release | |
| 310 | already touches that area. Neither justifies a tag. | |
| 311 | ||
| 312 | ## Housekeeping — v3.8.1 | |
| 254 | 313 | |
| 255 | 314 | - `Hutch/Hutch/App/AccountSession.swift` sits in a stray nested directory; |
| 256 | 315 | `Hutch/HutchTests/` is empty. |