fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

fix: make release artifacts fully offline - #582

Merged
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets
Aug 29, 2026
Merged

fix: make release artifacts fully offline#582
jjoonleo merged 1 commit into
mainfrom
feature/ios-sodium-native-assets

Conversation

@jjoonleo

Copy link
Copy Markdown
Contributor

Summary

  • replace deprecated prebuilt sodium_libs with sodium 4.0.4 native build hooks
  • preserve the existing Argon2id plus XChaCha20-Poly1305 backup format and behavior
  • bundle sodium.js, SQLite WASM, Drift worker, and CanvasKit locally for web
  • remove Firebase Messaging service worker registration, Google Sign-In bootstrap, and remote SQLite WASM URL
  • extend the local-only gate to reject remote web bootstrap resources and require local CanvasKit

Root cause

App Store Connect rejected build 1.1.0 (56) with error 91011 because the prebuilt libsodium.framework contained an arm64e slice compiled with the iOS 18.5 SDK. Xcode 26 requires arm64e slices to be built with the iOS 26 SDK or later. The official sodium 4 native-asset path compiles libsodium with the active SDK and produces an arm64-only iOS framework.

The web bootstrap also still loaded Google Sign-In, Firebase Messaging, and SQLite WASM from remote servers, which violated the product local-only boundary despite the Dart and native source gates passing.

Behavior and lifecycle

Backup creation and restore keep the same version 1 container, KDF parameters, authenticated encryption, password failure behavior, and atomic restore behavior. Native libsodium initialization is now supplied by sodium build hooks. Web startup loads every required runtime artifact from the deployed bundle and registers only the Flutter offline cache service worker.

Persistence and migration

No database, backup format, or user-data migration. Existing encrypted backups remain readable because algorithms, parameters, framing, and authenticated metadata are unchanged.

Concurrency and idempotency

Password derivation still runs through Sodium.runIsolated. Repeated dependency generation and release builds are stable. Reinstalling or updating the app does not rewrite existing local data.

Validation

  • flutter test: 552 passed
  • flutter analyze: no issues
  • local-only boundary: passed, including iOS remote notification and web bootstrap regressions
  • flutter build web --release: passed; WASM dry run passed
  • built web bundle contains local sodium.js, sqlite3.wasm, Drift worker, and CanvasKit
  • built web bootstrap contains no Firebase Messaging, Google Sign-In, unpkg, or remote SQLite markers
  • flutter build ipa --release --export-method app-store: passed
  • iOS sodium.framework is arm64 only; no framework contains arm64e
  • OnTime 1.1.0 (56), bundle club.devkor.ontime.ios

Out of scope

  • no backup format change
  • no app version or build-number change
  • no App Store metadata or production release change

Follow-up to #580 and #581.

@github-actions

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit cafa0c2):

https://on-time-front-widgetbook--pr-582-fmwqub7i.web.app

(expires Tue, 01 Sep 2026 01:55:18 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: e53128a376fed0209d449279de9c0d94c83cdd8b

@jjoonleo
jjoonleo merged commit 44067d7 into mainAug 29, 2026
3 checks passed
@jjoonleo
jjoonleo deleted the feature/ios-sodium-native-assets branch August 29, 2026 01:56
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@jjoonleo