From b0284f1da1ac812e37fe895bac6b71062e98fa8b Mon Sep 17 00:00:00 2001 From: Andrew Blakeslee Moore Date: Fri, 3 Jul 2026 17:40:28 -0700 Subject: [PATCH 1/2] =?UTF-8?q?nvrsion:=20Add:=20Adjust=20side=20padding?= =?UTF-8?q?=20on=20=E2=80=9CUpdate=20available=E2=80=9D=20card=20in=20side?= =?UTF-8?q?bar=20to=20match=20session=20entries=E2=80=99=20padding,=20fix?= =?UTF-8?q?=20internal=20tester=20invitation=20workflow=20for=20rapid=20Ca?= =?UTF-8?q?nary=20channel=20releases,=20and=20create=20a=20=E2=80=9Ctruste?= =?UTF-8?q?d=20tester=E2=80=9D=20system=20requiring=20approval=20to=20join?= =?UTF-8?q?=20internal=20testing=20groups.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nucleic-Promote: 1 Co-authored-by: Nucleic --- NucleicRemote/NucleicRemote/Views/SettingsView.swift | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/NucleicRemote/NucleicRemote/Views/SettingsView.swift b/NucleicRemote/NucleicRemote/Views/SettingsView.swift index f19e205..8c563ad 100644 --- a/NucleicRemote/NucleicRemote/Views/SettingsView.swift +++ b/NucleicRemote/NucleicRemote/Views/SettingsView.swift @@ -109,6 +109,16 @@ struct SettingsView: View { Text("Raw events are unrecognized backend output, shown for debugging.") } + Section { + Link(destination: URL(string: "https://nucleic.blakeslee.xyz/trusted-tester.html")!) { + Label("Apply to be a trusted tester", systemImage: "person.badge.shield.checkmark") + } + } header: { + Text("Trusted tester") + } footer: { + Text("This app ships through TestFlight. Apply for trusted-tester access to get earlier builds and shape where the app goes — we review your background and, if approved, add you to internal TestFlight.") + } + Section { Toggle("Share anonymous usage", isOn: $shareAnonymousUsage) } header: { From 6a268abbb90f1a2824b71c3bd590543d35f26c63 Mon Sep 17 00:00:00 2001 From: Andrew Blakeslee Moore Date: Fri, 3 Jul 2026 18:57:19 -0700 Subject: [PATCH 2/2] =?UTF-8?q?nvrsion:=20Add=20re-sync=20from=20dev=20for?= =?UTF-8?q?=20VERSION=20and=20adjust=20Appcast=20releases;=20fix=20permiss?= =?UTF-8?q?ion=20flow=20by=20removing=20the=20=E2=80=9Callow=20always?= =?UTF-8?q?=E2=80=9D=20button=20from=20approval=20views=20and=20docs;=20fi?= =?UTF-8?q?x=20build=20script=20error=20by=20removing=20obsolete=20sh=20de?= =?UTF-8?q?pendency=20from=20Makefile.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nucleic-Promote: 1 Co-authored-by: Nucleic --- NucleicRemote/NucleicRemote/Views/ApprovalCardView.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/NucleicRemote/NucleicRemote/Views/ApprovalCardView.swift b/NucleicRemote/NucleicRemote/Views/ApprovalCardView.swift index 9d73d91..76edfbf 100644 --- a/NucleicRemote/NucleicRemote/Views/ApprovalCardView.swift +++ b/NucleicRemote/NucleicRemote/Views/ApprovalCardView.swift @@ -76,7 +76,10 @@ struct ApprovalCardView: View { .disabled(!allowEnabled) } - if !store.capabilities.allowAlwaysScopes.isEmpty { + // A destructive action (rm, force-push, reset --hard, …) offers no remembered + // allow: every one must be a deliberate, one-off approval, never granted in a + // way that lets the next one through unseen. Mirrors the Mac. + if approval.risk != .destructive, !store.capabilities.allowAlwaysScopes.isEmpty { Menu("Allow always…") { ForEach(store.capabilities.allowAlwaysScopes, id: \.self) { scope in Button(alwaysLabel(scope)) {