SHA256
docs: record verified native preview and unfinished PWA parity
Replace current wrapper claims with native architecture/security/build evidence, preserve historical documents, track all thirty pages and explicit release gates, correct brand attribution and provide the twelve-section delivery report without claiming completion. Native signing remains paused and Apple application/device validation outstanding.
This commit is contained in:
1 parent
1433e1670a
commit
40a7962307
20 files changed
+813
-277
No files matched your search
@@ -2,6 +2,11 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- Begin the genuine native rebuild: Compose/SwiftUI screens, direct HTTPS API,
|
||||
protected native session storage and initial auth/dashboard/task/note/shopping
|
||||
flows. Archive the rejected WebView renderer and its tests. Full PWA parity is
|
||||
explicitly incomplete; see `docs/native-parity.md`.
|
||||
|
||||
- Gitea workflows for the maintainer's Ubuntu pool and native M4 Pro runner,
|
||||
explicit SDK/KVM prerequisites, SHA-256 checkout and unsigned-only CI release builds.
|
||||
|
||||
|
||||
+3
-1
@@ -11,7 +11,9 @@ Add regression tests with security fixes, and demonstrate that the test fails
|
||||
without the fix. Do not commit build outputs, credentials, private signing keys,
|
||||
local servers, generated fixture certificates, or production household data.
|
||||
|
||||
Keep platform integrations native and dependencies minimal. The server owns
|
||||
Keep all application screens native (Compose/SwiftUI), not just platform
|
||||
integrations. No WebView fallback for unfinished modules; use the parity tracker
|
||||
and never count archived browser tests as native evidence. Keep dependencies minimal. The server owns
|
||||
business logic, authentication, CSRF, and authorization. Never solve compatibility
|
||||
by disabling TLS, accepting every origin, or copying a browser's session cookies.
|
||||
Upstream prohibits frontend frameworks, bundlers, and transpilers in its own
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
# Yuvomi Mobile
|
||||
|
||||
Independent, community-maintained Android (Kotlin/WebView) and iOS
|
||||
(SwiftUI/WKWebView) companions for user-owned [Yuvomi](https://github.com/ulsklyc/yuvomi)
|
||||
servers. Not affiliated with or endorsed by upstream.
|
||||
Independent native Android (Kotlin/Jetpack Compose) and iOS (SwiftUI) clients for
|
||||
user-owned [Yuvomi](https://github.com/ulsklyc/yuvomi) servers. Not affiliated with
|
||||
or endorsed by upstream.
|
||||
|
||||
**Development build - not production-ready.** See [validation status](docs/validation.md).
|
||||
**Native rebuild in progress — not full PWA parity or production-ready.**
|
||||
The previous WebView wrapper did not meet the requested native implementation.
|
||||
It is archived under `legacy/` and is not the shipped application surface.
|
||||
Read the [feature-by-feature parity tracker](docs/native-parity.md) and
|
||||
[current validation](docs/validation.md) before installing a preview.
|
||||
No mobile backend, advertisements, telemetry, tracking, subscriptions, or mandatory cloud.
|
||||
The configured server supplies the application and retains responsibility for its own
|
||||
integrations, version checks, security and privacy.
|
||||
The apps render native controls and call the existing server API. The server owns
|
||||
authorization, recurrence, synchronization and household business rules.
|
||||
|
||||
Use a root-hosted HTTPS instance with a valid certificate, including private servers
|
||||
accessible through your VPN. Custom ports are supported. HTTP and subpath deployments
|
||||
are intentionally rejected. Enter the server on first launch; use Server settings to
|
||||
reconnect or erase local browsing data and switch installations.
|
||||
are intentionally rejected. Enter the server on first launch; use **Mehr** to
|
||||
remove the native session and switch installations. The native client does not
|
||||
import a browser/WebView session; sign in again after upgrading the prototype.
|
||||
|
||||
- [Architecture](docs/architecture.md)
|
||||
- [Native preview delivery report](docs/native-delivery-report.md)
|
||||
- [Android build](docs/build-android.md) / [iOS build](docs/build-ios.md)
|
||||
- [Compatibility and authentication](docs/server-compatibility.md)
|
||||
- [Release process](docs/release-process.md)
|
||||
|
||||
+53
-1
@@ -1,4 +1,56 @@
|
||||
# Security policy
|
||||
# Security policy — native rebuild
|
||||
|
||||
**The current native client is an incomplete development preview, not an audited
|
||||
release or full PWA replacement.** See [native parity](docs/native-parity.md).
|
||||
|
||||
Report vulnerabilities privately to the repository owner through an established
|
||||
private channel. No reporting mailbox has been provided; do not invent one or put
|
||||
cookies, keys, household records or exploit details into public issues. Upstream
|
||||
server vulnerabilities belong in its private reporting channel.
|
||||
|
||||
## Current native security model
|
||||
|
||||
- Native Compose/SwiftUI screens call one configured HTTPS origin. System TLS
|
||||
validation is mandatory and API redirects are refused. No WebView/WKWebView is
|
||||
shipped as the app surface or used as a missing-feature fallback.
|
||||
- Passwords and second-factor codes exist transiently for the API request; they
|
||||
are not saved to preferences, keychains, logs, artifacts or application state
|
||||
restoration. Server cookies, not passwords, persist the session.
|
||||
- Android persists allow-listed Secure cookies with their absolute expiry in
|
||||
AES-GCM ciphertext backed by AndroidKeyStore, with the origin authenticated as
|
||||
additional data. iOS uses a private ephemeral URLSession jar and origin-scoped
|
||||
Keychain items protected with WhenUnlockedThisDeviceOnly.
|
||||
- CSRF tokens follow the upstream API protocol. Only an explicit `csrf_invalid`
|
||||
rejection allows one refresh/retry. Other permission errors or ambiguous network
|
||||
failures never cause automatic mutation replay. The server remains authoritative
|
||||
for authorization, recurrence, reward accounting and cross-module rules.
|
||||
- Reads are bounded and timed out. There is no offline mutation queue or native
|
||||
remote push implementation. Missing features are documented, not simulated.
|
||||
- Logout attempts remote revocation and clears the native local session. Local
|
||||
server removal is not remote revocation. Old prototype WebKit data is not
|
||||
imported; use OS app-data removal/reinstall to erase that legacy installation.
|
||||
- Android screenshots are blocked. The iOS view is obscured while inactive. The
|
||||
Android integration test temporarily permits a screenshot only of its synthetic
|
||||
private fixture, restores the restriction and never uses real household data.
|
||||
- The owner-authorized initial signing key is backed up outside the repository.
|
||||
Four repository signing secrets exist, but signing/release changes are parked
|
||||
during the native rebuild. No private key belongs in Git or downloadable CI
|
||||
artifacts. Protect trusted-branch write access and isolate persistent runners.
|
||||
|
||||
## Mandatory gates
|
||||
|
||||
Native transports, secure storage, session erasure, actual Apple SDK compilation,
|
||||
real-device behavior, accessibility, supported authentication flows and dependency
|
||||
resolution need review and evidence before release. OIDC, file transfers, offline
|
||||
storage and the remaining modules are not implemented native capabilities yet.
|
||||
Advisory scans and parser/unit checks are not a guarantee that code is secure.
|
||||
|
||||
The superseded prototype policy is retained below as historical context only;
|
||||
it must not be used to claim capabilities of the native rebuild.
|
||||
|
||||
---
|
||||
|
||||
## Historical WebView prototype policy
|
||||
|
||||
**Development software: no production-readiness claim.** Only the current
|
||||
development branch is maintained; no stable mobile release exists yet.
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
|
||||
Yuvomi Mobile is an independent community contribution, not an official Yuvomi
|
||||
product. Yuvomi's name identifies the server with which it interoperates.
|
||||
Visual color values follow upstream DESIGN.md. No upstream logo is redistributed.
|
||||
Native design-token mappings follow upstream DESIGN.md/styles. The native
|
||||
three-circle brand mark is redrawn from upstream's published brand geometry and
|
||||
colors (`public/utils/brand-mark.js` and `docs/logo.svg`); its MIT attribution is
|
||||
preserved below. No affiliation or trademark ownership is implied.
|
||||
|
||||
Upstream Yuvomi: https://github.com/ulsklyc/yuvomi
|
||||
|
||||
|
||||
+43
-32
@@ -1,41 +1,52 @@
|
||||
# Architecture
|
||||
# Native client architecture
|
||||
|
||||
Two independent native applications share a policy, not a cross-platform runtime:
|
||||
The requested product is a native reconstruction of Yuvomi's PWA, not a native
|
||||
window around that website. Both shipping entry points now render native views:
|
||||
|
||||
| Responsibility | Android | iOS |
|
||||
| --- | --- | --- |
|
||||
| Native entry/configuration | ComponentActivity and platform widgets | SwiftUI |
|
||||
| Web application | Android WebView | WKWebView |
|
||||
| Server URL policy | ServerAddress | ServerAddress |
|
||||
| Reachability/metadata | HttpsURLConnection, no redirects/cookies | Ephemeral URLSession, no redirects/cookies |
|
||||
| Authentication | Upstream web UI and OS cookie jar | Upstream web UI and WKWebsiteDataStore |
|
||||
| OIDC | Separate restricted web view after consent | Separate restricted web view after consent |
|
||||
| Downloads | Origin-bound streaming / bounded blob capture and pull | WKDownload to temporary protected file, system export |
|
||||
| Screens and navigation | Jetpack Compose / Material 3 primitives, Yuvomi tokens | SwiftUI, Yuvomi tokens |
|
||||
| Application state | AndroidViewModel + Compose state | MainActor ObservableObject |
|
||||
| JSON API | HttpsURLConnection, serialized worker | URLSession actor, bounded streaming delegate |
|
||||
| Session ownership | Explicit origin-bound secure-cookie jar | Private ephemeral URLSession cookie storage |
|
||||
| Persistent cookies | AES-GCM, AndroidKeyStore key, origin as authenticated data | Keychain, WhenUnlockedThisDeviceOnly, origin-scoped account |
|
||||
| Server logic | Existing unmodified Yuvomi API | Existing unmodified Yuvomi API |
|
||||
|
||||
The client never reimplements a Yuvomi module or introduces a backend. The user
|
||||
selects the origin. Bootstrap calls check the actual upstream unauthenticated
|
||||
metadata contract before loading the server application. Configuration stores only
|
||||
the origin and a query/fragment-free last path; auth/reset/invite routes are not
|
||||
restored. No native password or API-token storage exists.
|
||||
There is no WebView/WKWebView in either shipped source tree and no browser
|
||||
fallback for missing modules. The old implementation and browser tests are
|
||||
archived in `legacy/`; their results are historical, not evidence for this client.
|
||||
|
||||
The current web view remains alive across background/resume and ordinary rotation.
|
||||
Android handles orientation changes in the existing activity; process recreation
|
||||
loads the remembered path and retains OS cookies, not unsaved web form memory.
|
||||
iOS retains a StateObject-owned view; cold launch restores path and persistent
|
||||
cookies. No resume reload is imposed. Native recovery offers Retry, Keep viewing,
|
||||
and server management without hiding the route back to configuration.
|
||||
The first native slice contains HTTPS onboarding, setup/password/TOTP login,
|
||||
session restoration, a basic dashboard, task/note/shopping interactions, read-only
|
||||
permission handling and local sign-out/server removal. Exact feature and visual
|
||||
parity is tracked in [native parity](native-parity.md), not inferred from a list of
|
||||
navigation destinations. The other modules remain unfinished.
|
||||
|
||||
Server erasure destroys the browsing context and clears all website storage before
|
||||
another server is loaded. The local wipe does not invalidate the remote session;
|
||||
logout is still a server-side operation. Web application history remains native
|
||||
web history. External schemes, universal links and app links are not registered
|
||||
because arbitrary self-hosted domains cannot be verified by this app in advance.
|
||||
## Transport and state boundaries
|
||||
|
||||
The optional integration build has a different Android package ID and adds trust
|
||||
for a fresh test CA generated outside the repository. It uses the same production
|
||||
code and the unmodified pinned upstream server. Neither normal debug nor release
|
||||
resources include that CA. Never distribute an integration APK.
|
||||
- One configured root HTTPS origin/port; system certificate validation only.
|
||||
- API calls never follow redirects. No cookie or Authorization state is replayed
|
||||
to another host. Authentication proxies returning HTML are not treated as APIs.
|
||||
- JSON reads have byte limits and timeouts. Writes are not queued for offline
|
||||
replay. Only a server-declared `csrf_invalid` rejection permits one token refresh
|
||||
and retry; ordinary authorization failures and transport failures do not.
|
||||
- Server session cookies are persisted, not passwords or TOTP/recovery codes.
|
||||
Session-only cookies are not converted to long-lived cookies.
|
||||
- Native UI mutations wait for the server result. Permissions remain enforced
|
||||
server-side; sparse module/widget permissions also control native affordances.
|
||||
- Local removal clears the native cookie vault and in-memory records. It is not
|
||||
remote revocation. Logout attempts server revocation and still erases the local
|
||||
session if the server cannot be reached.
|
||||
- A prior WebView prototype installation may retain its old OS website data.
|
||||
This data is never imported by the native client. Clear app data/reinstall the
|
||||
prototype before reviewing this native preview if complete legacy erasure is
|
||||
required; no migration of private household records is performed.
|
||||
|
||||
Read-only offline functionality belongs to upstream's service worker. The app
|
||||
preserves it where the platform engine supports it, but does not promise offline
|
||||
editing, synchronization, or the same PWA cache behavior on all OS versions.
|
||||
## Explicit gaps
|
||||
|
||||
No native OIDC handoff has been implemented. A browser sign-in is not represented
|
||||
as a successful native API session. Password reset/invitation flows, the remaining
|
||||
modules, configurable dashboard, uploads/downloads, notification integrations,
|
||||
offline cache, localization parity and visual baseline comparison remain open.
|
||||
The signing setup was paused by the maintainer's native-rebuild correction; it
|
||||
must not be used to label this incomplete client as a finished release.
|
||||
+21
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
Requirements: JDK 17, Android SDK platform 37.0, build-tools 36.0.0, current
|
||||
platform-tools, and accepted Android SDK licenses. Minimum Android 8 (API 26).
|
||||
Use a maintained Android System WebView. Target API 37. On Android 17, choose
|
||||
"Allow private-network servers" when using a LAN instance; public HTTPS servers
|
||||
The application surface is Jetpack Compose, not Android System WebView. Target
|
||||
API 37. On Android 17, choose "Zugriff auf private Netzwerke erlauben" for a LAN instance; public HTTPS servers
|
||||
do not need this optional runtime permission. No discovery/scanning is performed.
|
||||
|
||||
```sh
|
||||
@@ -13,7 +13,7 @@ bash android/gradlew -p android connectedDebugAndroidTest
|
||||
```
|
||||
|
||||
Gradle 9.6.0 is checksum-verified by the wrapper. AGP 9.4.1 uses built-in Kotlin
|
||||
with the build-cache fix in KGP 2.4.21. Maven versions are locked. No dynamic
|
||||
with KGP and Compose compiler plugin 2.4.21. Maven versions are locked. No dynamic
|
||||
application dependencies or private Maven repository is required.
|
||||
|
||||
Ordinary outputs:
|
||||
@@ -23,6 +23,14 @@ Ordinary outputs:
|
||||
- `android/app/build/outputs/bundle/release/app-release.aab` (unsigned unless signed later)
|
||||
- `android/app/build/reports/` (lint, JVM and emulator results)
|
||||
|
||||
The Gitea build job uploads `android-native-debug-apk`, containing an installable
|
||||
development-signed `app-debug.apk`. It is a native preview, not a signed stable
|
||||
release or a claim of full PWA parity. See `native-parity.md` before testing it.
|
||||
|
||||
Native UI tests live in `src/androidTestNative/java` and the real-server native
|
||||
scenario in `src/androidTestNativeIntegration/java`. The old browser tests and
|
||||
renderer are archived under `legacy/` and are not compiled into the app/suites.
|
||||
|
||||
Immediately after building, collect and inspect the outputs:
|
||||
|
||||
```sh
|
||||
@@ -60,6 +68,16 @@ Requires Node 22.14+ and a running emulator. The harness creates and removes its
|
||||
own CA/key/database, uses `adb reverse`, and builds `.integration` with explicit
|
||||
test trust. It does not weaken production TLS. Test credentials are ephemeral.
|
||||
Keep test reports private if you customize the harness with real data (not advised).
|
||||
The native test calls the real API through native controls and saves a synthetic
|
||||
dashboard screenshot under `app/build/outputs/native-screenshots/`. It does not
|
||||
demonstrate native SSO merely because the protocol fixture also tests OIDC.
|
||||
The test writes through `PlatformTestStorageRegistry`; AGP collects the file in
|
||||
`outputs/connected_android_test_additional_output/integrationAndroidTest/` before
|
||||
uninstalling the fixture. The harness rejects missing/ambiguous output and removes
|
||||
only its known screenshot from previous runs. Do not extract app-private files
|
||||
after Gradle returns: UTP has already uninstalled the `.integration` package.
|
||||
Capture uses the native window and asserts nonuniform pixels; a valid PNG header
|
||||
alone is not sufficient screenshot evidence.
|
||||
|
||||
For dependency updates run `:app:dependencies --write-locks`, the full pipeline,
|
||||
and `python3 scripts/check-dependencies.py`. Review lockfile changes. The version
|
||||
|
||||
+8
-4
@@ -1,8 +1,8 @@
|
||||
# iOS development
|
||||
|
||||
Requires macOS, Xcode 16.4 or newer with an iOS simulator, and XcodeGen 2.44.1.
|
||||
Minimum iOS/iPadOS 18.4: the auth window must be able to deny native file-panel
|
||||
requests, which earlier WKWebView delegates cannot do. No CocoaPods or external
|
||||
Minimum iOS/iPadOS 18.4 is retained for this rebuild. The application surface is
|
||||
SwiftUI; the old WKWebView renderer is archived, not shipped. No CocoaPods or external
|
||||
runtime package is required. For App Store submission use Apple's currently
|
||||
required Xcode/iOS SDK, not merely the oldest compiler that can build the source.
|
||||
|
||||
@@ -29,11 +29,15 @@ swift test --package-path ios
|
||||
swiftc -frontend -parse ios/Sources/*.swift ios/Tests/*.swift ios/UITests/*.swift
|
||||
```
|
||||
|
||||
These portable tests compile the **production URL/metadata policies only**.
|
||||
Parsing does not typecheck UIKit, SwiftUI or WebKit APIs. Neither command is
|
||||
These portable tests compile the **production Foundation API transport, contracts
|
||||
and URL/metadata policies**. Parsing does not typecheck SwiftUI or Security APIs. Neither command is
|
||||
evidence that the iOS application builds. Actual Xcode testing is mandatory.
|
||||
|
||||
For a device build select your authorized development team in Xcode, use your own
|
||||
registered bundle identifier, and let Xcode manage development provisioning.
|
||||
Never commit generated profiles or certificates. See `release-process.md` for
|
||||
distribution. A Linux environment cannot produce a validated iOS archive.
|
||||
|
||||
The Mac runner now bootstraps checksum-pinned native Node 22 before checkout,
|
||||
because its JavaScript actions cannot start without Node in the service PATH.
|
||||
This does not install/choose Xcode, accept its license or create a simulator.
|
||||
@@ -42,6 +42,12 @@ Xcode 16.4+ (or a current release supporting this project), accept its license a
|
||||
complete first-launch setup. Install an iOS 18.4+ simulator runtime and create an
|
||||
available iPhone simulator; `select-simulator.py` chooses the newest eligible one.
|
||||
|
||||
Before the first JavaScript action, an inline shell bootstrap installs verified
|
||||
native Node 22.22.1 into a versioned runner tool cache and exports its bin directory
|
||||
through `GITHUB_PATH`. It needs no Homebrew/root access and remains available to
|
||||
action post-cleanup. This addresses run #4's `Cannot find: node in PATH` failure;
|
||||
the modified workflow itself still needs a real Mac run.
|
||||
|
||||
XcodeGen's pinned, checksum-verified binary includes native arm64 and x86_64
|
||||
slices; Rosetta/Homebrew installation is not required by the workflow. Build,
|
||||
archive and Swift package scratch outputs use `RUNNER_TEMP`. Scratch directories
|
||||
|
||||
+52
-1
@@ -1,4 +1,55 @@
|
||||
# Maintainer continuation
|
||||
# Native rebuild continuation
|
||||
|
||||
## Current objective — do not restore the wrapper
|
||||
|
||||
The maintainer rejected the browser-wrapper architecture and requested the PWA's
|
||||
appearance/functions implemented as genuine native screens. Shipping Android now
|
||||
uses Compose and iOS SwiftUI, calling the existing API directly. `legacy/` holds
|
||||
the superseded renderers/tests for reference only. No WebView fallback, raw-JSON
|
||||
module placeholder or old browser-test pass may be represented as native parity.
|
||||
|
||||
Read [native parity](native-parity.md), [architecture](architecture.md), and
|
||||
[current validation](validation.md) first. Initial auth/dashboard/tasks/notes/
|
||||
shopping slices exist, but **no module has accepted full visual/functional parity**.
|
||||
The remaining pages/settings/auth/file/offline/notification work is explicit.
|
||||
|
||||
The owner-authorized signing key and four Gitea secrets were created before this
|
||||
correction. Their private backup is `/home/neste/yuvomi-signing/initial-20261021`.
|
||||
Do not print its contents. Uncommitted signing changes are preserved in Git stash
|
||||
`wip: owner-authorized signing setup paused for true native rewrite`; do not apply
|
||||
them blindly or resume signing/publishing the old wrapper.
|
||||
|
||||
Current local native outputs/logs:
|
||||
|
||||
- `/home/neste/yuvomi-native-build` (use `YUVOMI_BUILD_DIR` on WSL).
|
||||
- `/home/neste/yuvomi-native-validation.log` and native integration logs.
|
||||
- `/home/neste/yuvomi-native-swift` and `/home/neste/yuvomi-native-swift.log`.
|
||||
- The existing persistent SDK, Swift, ktlint, actionlint and unmodified upstream
|
||||
paths listed below remain usable. Set `ANDROID_SERIAL=emulator-5554`; do not
|
||||
authorize or deploy to unrelated devices visible in `adb devices`.
|
||||
|
||||
Run native JVM/Compose UI tests, the real upstream fixture, portable Swift API/
|
||||
contract tests, formatting, lint and OSV after changes. Apple UI/Security.framework
|
||||
is not typechecked by Linux. Gitea's Mac job now bootstraps pinned Node before
|
||||
checkout, but actual Xcode results still need inspection. Ubuntu emulator jobs
|
||||
continue requiring accessible KVM; do not weaken or fake that evidence.
|
||||
|
||||
Latest local native evidence: 10 JVM tests, 6 API-35 Compose tests, 7 real-server
|
||||
instrumentation tests (including those same 6), both lint variants and native
|
||||
debug/unsigned release APK/AAB builds pass. Sixteen portable Swift tests and strict
|
||||
format/parsing pass. Screenshot export now uses AndroidX test storage/AGP output
|
||||
collection before uninstall; the PNG was opened and confirmed nonblank. Five new
|
||||
output-regression tests guard missing, invalid, ambiguous and stale screenshots.
|
||||
See `validation.md` for logs and limitations. No Apple SDK result is implied.
|
||||
|
||||
The next Mac/Ubuntu workflow execution still needs inspection after pushing.
|
||||
Rebuild/collect from a clean checkout; do not present cached wrapper artifacts as
|
||||
the native preview. Keep the signing stash parked.
|
||||
|
||||
Next work: stabilize/visually compare this slice, close auth/advanced CRUD gaps,
|
||||
then implement the remaining real native modules against the parity inventory.
|
||||
|
||||
## Historical environment and original delivery context
|
||||
|
||||
This is a development delivery, not authorization to publish. Preserve the Git
|
||||
history on `feat/yuvomi-mobile`; use Conventional Commits and normal pushes only.
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Historical architecture — superseded WebView prototype
|
||||
|
||||
Two independent native applications share a policy, not a cross-platform runtime:
|
||||
|
||||
| Responsibility | Android | iOS |
|
||||
| --- | --- | --- |
|
||||
| Native entry/configuration | ComponentActivity and platform widgets | SwiftUI |
|
||||
| Web application | Android WebView | WKWebView |
|
||||
| Server URL policy | ServerAddress | ServerAddress |
|
||||
| Reachability/metadata | HttpsURLConnection, no redirects/cookies | Ephemeral URLSession, no redirects/cookies |
|
||||
| Authentication | Upstream web UI and OS cookie jar | Upstream web UI and WKWebsiteDataStore |
|
||||
| OIDC | Separate restricted web view after consent | Separate restricted web view after consent |
|
||||
| Downloads | Origin-bound streaming / bounded blob capture and pull | WKDownload to temporary protected file, system export |
|
||||
|
||||
The client never reimplements a Yuvomi module or introduces a backend. The user
|
||||
selects the origin. Bootstrap calls check the actual upstream unauthenticated
|
||||
metadata contract before loading the server application. Configuration stores only
|
||||
the origin and a query/fragment-free last path; auth/reset/invite routes are not
|
||||
restored. No native password or API-token storage exists.
|
||||
|
||||
The current web view remains alive across background/resume and ordinary rotation.
|
||||
Android handles orientation changes in the existing activity; process recreation
|
||||
loads the remembered path and retains OS cookies, not unsaved web form memory.
|
||||
iOS retains a StateObject-owned view; cold launch restores path and persistent
|
||||
cookies. No resume reload is imposed. Native recovery offers Retry, Keep viewing,
|
||||
and server management without hiding the route back to configuration.
|
||||
|
||||
Server erasure destroys the browsing context and clears all website storage before
|
||||
another server is loaded. The local wipe does not invalidate the remote session;
|
||||
logout is still a server-side operation. Web application history remains native
|
||||
web history. External schemes, universal links and app links are not registered
|
||||
because arbitrary self-hosted domains cannot be verified by this app in advance.
|
||||
|
||||
The optional integration build has a different Android package ID and adds trust
|
||||
for a fresh test CA generated outside the repository. It uses the same production
|
||||
code and the unmodified pinned upstream server. Neither normal debug nor release
|
||||
resources include that CA. Never distribute an integration APK.
|
||||
|
||||
Read-only offline functionality belongs to upstream's service worker. The app
|
||||
preserves it where the platform engine supports it, but does not promise offline
|
||||
editing, synchronization, or the same PWA cache behavior on all OS versions.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Historical server compatibility — superseded WebView prototype
|
||||
|
||||
Source reference: upstream 2.78.0 revision
|
||||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`. No general version range has been
|
||||
certified. Anonymous bootstrap metadata deliberately omits the exact version;
|
||||
native probing verifies shape, not an invented minimum-version comparison.
|
||||
|
||||
Use `https://family.example.com` or `https://family.example.com:8443`, backed by a
|
||||
root-hosted Yuvomi installation and a valid system-trusted certificate. Operators
|
||||
should set `SESSION_SECURE=true`, correct `BASE_URL`, and correct proxy trust.
|
||||
Private servers are supported through reachable HTTPS/VPN, not TLS bypasses.
|
||||
International hostnames should be entered in ASCII/punycode for both platforms.
|
||||
|
||||
Root-relative assets, API endpoints, cookie paths, callback redirects and worker
|
||||
registration mean `/yuvomi/` subpaths are not supported by the inspected source.
|
||||
Use a dedicated hostname. Reverse proxies must pass `/api/v1/*`, cookies, HTML,
|
||||
JavaScript and the service worker consistently. An external authentication proxy
|
||||
that intercepts bootstrap calls is rejected with a connection error; it is not
|
||||
silently identified as a Yuvomi server.
|
||||
|
||||
## Authentication
|
||||
|
||||
Password login, TOTP/recovery codes, password reset, invitations, server-side
|
||||
session expiry/revocation and logout remain upstream web flows. No native code
|
||||
stores the password, supplies a CSRF bypass, or extends an expired session.
|
||||
Backgrounding does not clear cookies. Native server erasure does not revoke a
|
||||
remote session; use Yuvomi logout first or revoke sessions server-side.
|
||||
|
||||
### OIDC: local fixture verified; real-provider validation pending
|
||||
|
||||
The initiating Yuvomi session contains OIDC state, nonce and PKCE verifier. When
|
||||
the server redirects to an identity provider, native consent offers an isolated
|
||||
web sign-in window sharing the OS website cookie store. HTTPS-only redirects
|
||||
can return to the server callback; the final same-origin page returns to the main
|
||||
view. No app-capability handlers or JS bridge are installed in that auth window.
|
||||
|
||||
Some providers (including configurations that prohibit embedded user agents)
|
||||
require a system browser. **Those cannot sign the native view in with upstream's
|
||||
current protocol.** Use Server settings -> Open server in browser, and sign in
|
||||
there for an independent browser session. Opening only the external authorization
|
||||
link in a browser does not transfer the initiating cookie. Browser cookies are
|
||||
never copied into the app, and custom-scheme callbacks are not fabricated.
|
||||
|
||||
The API 35 integration suite completes a native isolated-window round trip with
|
||||
a local test IdP, real RS256 ID tokens, nonce and S256 PKCE. No external
|
||||
IdP/developer account was supplied. Validate the actual provider, including
|
||||
cross-site cookies, cancellation, errors, TOTP and account linking, before relying
|
||||
on that deployment. iOS authentication has not run against Apple SDKs. A native
|
||||
browser handoff would require an independently reviewed upstream protocol; no
|
||||
such upstream change is included or published.
|
||||
|
||||
Android generated exports require a current WebView supporting document-start
|
||||
scripts and are capped at 25 MB. A bounded Blob registry preserves a generated
|
||||
file even when upstream immediately revokes its object URL; it does not fetch
|
||||
blob URLs or alter the server's CSP. HTTPS file downloads are capped at 100 MB.
|
||||
Update the system WebView if generated exports are unavailable on an old engine.
|
||||
|
||||
## Notifications and offline
|
||||
|
||||
Upstream implements Web Push and optional ntfy/Gotify/webhook/email channels.
|
||||
Embedded web views do not supply a portable native push subscription. This app
|
||||
has **no native remote-push claim**, no Firebase/APNs secrets, no background
|
||||
polling service, and no fake notification-registration UI. Configure an existing
|
||||
optional upstream ntfy/Gotify channel and its client if desired. No centralized
|
||||
service is required by this application.
|
||||
|
||||
Upstream service-worker caching is read-only, allow-listed, and versioned.
|
||||
Mutations/authentication remain online. Platform-specific cache/resume behavior
|
||||
and offline account switching still need device validation. Do not rely on offline
|
||||
editing, synchronization, or closed-app push in this native development build.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Historical security review — superseded WebView prototype
|
||||
|
||||
This is an engineering review, not an independent penetration test or certification.
|
||||
|
||||
Addressed during implementation:
|
||||
|
||||
- Canonical, HTTPS-only origin/port comparison; credential, fragment, query,
|
||||
subpath, scheme, lookalike-host and TLS-downgrade regression cases.
|
||||
- A main-frame POST can bypass Android's usual navigation callback. The request
|
||||
interception gate now rejects **all** cross-origin requests, not only subresources.
|
||||
The emulator regression was observed failing when the main-frame guard was
|
||||
deliberately removed, then rerun with the fix restored.
|
||||
- TLS failures cancel by default. Native download redirects are refused before
|
||||
cookies can be replayed to another origin. Bootstrap requests use neither
|
||||
cookies nor automatic redirects and have bounded metadata reads/timeouts.
|
||||
- Files use explicit system selection/content URIs; no filesystem or storage
|
||||
permission is granted to web content. Blob exports have no native JS bridge.
|
||||
- Complete Android browsing-data deletion uses WebStorageCompat, with OS app
|
||||
reset for engines without that capability. WebStorage.deleteAllData alone was
|
||||
insufficient for service-worker CacheStorage/IndexedDB and is not relied upon.
|
||||
- iOS server erase replaces the WKWebView, not only its URL, eliminating old
|
||||
history/back-forward contexts as well as persistent website data.
|
||||
- iOS metadata uses typed decoding, rejecting numeric values masquerading as booleans.
|
||||
- Native picker results are bound to the browsing generation/request. Android
|
||||
rejects stale upload/download selections, revokes camera URI grants, and clears
|
||||
capture cache on erasure. iOS ignores export-cancellation callbacks from an old
|
||||
download. Apple-specific callback regressions have not run without Xcode.
|
||||
- KGP was upgraded after OSV identified CVE-2026-53914 in the original build tool.
|
||||
The final OSV scan found no listed advisories across 213 locked/direct Maven
|
||||
coordinates and build plugins. Rescan after resolution/lock updates.
|
||||
- The inspected release APK is not debuggable, rejects cleartext, disables backup
|
||||
and trusts system CAs only. AndroidX's exported profile installer receiver is
|
||||
protected by the system DUMP permission; app providers are not exported.
|
||||
|
||||
Release gates still requiring evidence:
|
||||
|
||||
- Actual Xcode typecheck, simulator, archive, physical-device and accessibility review.
|
||||
- End-to-end IdP flows, especially providers that prohibit embedded agents; no
|
||||
browser-to-native session transfer is supported by the current upstream protocol.
|
||||
- iOS unknown-length download disk-pressure behavior; a post-download size check
|
||||
is not a streaming quota. Verify file picker/camera cancellation on real devices.
|
||||
- Android file-picker/camera/rotation while a picker is outstanding; cancellation
|
||||
on process death intentionally loses the selection, never silently retries it.
|
||||
- Offline sign-out/account switching, stale-worker updates and server erasure on
|
||||
current WebView/WKWebView versions. Upstream tests are not native device proof.
|
||||
- Reverify final signed release manifests, signing, store ownership, private vulnerability contact
|
||||
and applicable privacy disclosures. No claim that all vulnerabilities are absent.
|
||||
@@ -0,0 +1,146 @@
|
||||
# Historical validation — superseded WebView prototype
|
||||
|
||||
These results describe the old wrapper, not the current native implementation.
|
||||
See [current native validation](validation.md).
|
||||
|
||||
**Partially verified development software, not production-ready.**
|
||||
Local validation date: 2026-10-21. No unexecuted iOS application test, hosted CI
|
||||
run, production signing, or store publication is represented as completed.
|
||||
|
||||
## Executed evidence
|
||||
|
||||
- Android debug APK and unsigned release APK/AAB built successfully; both
|
||||
`lintDebug` and `lintRelease` passed. JVM security/picker-policy tests: **7 passed,
|
||||
zero failures/skips**.
|
||||
- Android API 35 regular emulator suite: **6 passed, zero failures/skips**.
|
||||
This covers onboarding, invalid URLs, background/resume, hardened settings,
|
||||
cross-origin POST/subresource isolation, opaque-page Blob rejection and activity
|
||||
recreation. Its permission test checks that the API 37 permission UI is absent;
|
||||
it is **not** evidence of API 37 permission grant/denial behavior.
|
||||
- Unmodified pinned upstream ran behind a temporary HTTPS reverse proxy.
|
||||
Bootstrap metadata, password login, Secure/HttpOnly/SameSite cookies, persistent
|
||||
session, CSRF rejection, logout/revocation passed in the harness.
|
||||
- Android's extended real-server scenario exercises login, HttpOnly cookies,
|
||||
document upload via upstream fetch, native FileTransfer output, bounded Blob
|
||||
export, background/resume, recreation, CSRF-protected logout, revocation,
|
||||
recovery, isolated OIDC return and back navigation. It does not automate the OS
|
||||
camera/document destination picker or prove every upstream module works.
|
||||
Two consecutive API 35 runs have **7 passed, zero failures/skips each**, including the
|
||||
six regular security/onboarding cases and this real-server scenario.
|
||||
- The cross-origin POST regression was deliberately observed failing without its
|
||||
guard. The production guard was restored and the API 35 regression passes.
|
||||
- Portable Swift production-policy tests: 7 passed (URL and typed metadata).
|
||||
All Swift sources passed format lint and parsing with Swift 6.2.1 on Linux.
|
||||
The portable package excludes BrowserModelTests. This does not build iOS.
|
||||
- Selected upstream suites ran successfully: cookie-secure-flag (4),
|
||||
session-sliding (8), two-factor (22), password-reset (24), sw-api-cache (42).
|
||||
Upstream's plain OIDC script also exited successfully. These are upstream tests,
|
||||
not evidence of a provider round-trip or native push support.
|
||||
- The HTTPS harness independently passed upstream OIDC discovery, RS256 ID-token
|
||||
signature/nonce validation, S256 PKCE exchange and session creation with a local
|
||||
test IdP. The fixture checks single-use codes, exact redirect URIs and OAuth
|
||||
Basic client authentication. Loopback hosts/ports and automatic fixture consent
|
||||
are not representative of every provider's cross-site/embedded-agent policies.
|
||||
- OSV: no listed advisories for **213** locked/direct Maven coordinates and build
|
||||
plugins at scan time. This is not a guarantee that no vulnerabilities exist.
|
||||
- ktlint 1.7.1, actionlint 1.7.7, repository invariants, Python compilation,
|
||||
Node syntax and shell syntax checks passed. JUnit-verifier regression suite:
|
||||
**8 passed**, including rejection of absent, empty, malformed, insufficient,
|
||||
failed, errored and skipped evidence.
|
||||
- Release APK inspection confirms API 26 minimum / API 37 target, no debuggable
|
||||
flag, backups and cleartext disabled, system-only certificate trust. Exported
|
||||
entry points are the launcher and AndroidX ProfileInstallReceiver protected by
|
||||
the system DUMP permission; file/startup providers are not exported. Debug APK
|
||||
signature verifies; release APK/AAB are unsigned. Collected archives contain no
|
||||
fixture CA/key or signing-key files.
|
||||
|
||||
## Emulator limitations and retry evidence
|
||||
|
||||
Earlier extended-suite attempts crashed the host emulator with SIGSEGV under
|
||||
software/off GPU modes. Host-GPU mode remained running and produced actionable
|
||||
JUnit failures: an OIDC-return synchronization timeout, followed by an outage
|
||||
assertion that incorrectly assumed the upstream worker could not serve its cached
|
||||
app shell, then a document-readiness race after recreation. Tests now verify the
|
||||
loaded JavaScript origin, wait for the sign-in window to close, retry only a probe
|
||||
lost to document replacement and exercise recovery through uncached metadata.
|
||||
The completed retry passes all seven tests without disabling the worker or
|
||||
weakening production TLS/CSP/origin policies.
|
||||
|
||||
API 37 attempts encountered broken package/activity services and locked
|
||||
credential-encrypted storage. **No API 37 runtime pass is claimed.**
|
||||
|
||||
Local logs and reports live in `/home/neste/yuvomi-build/`; test XML is under
|
||||
`app/outputs/androidTest-results/connected/`. Earlier failing JUnit snapshots are
|
||||
preserved as `integration-host-gpu-oidc-race.xml` and
|
||||
`integration-host-gpu-sw-cache.xml`, plus
|
||||
`integration-host-gpu-document-ready.xml`. Passing evidence is preserved in
|
||||
`integration-api35-first-pass.xml` and `integration-api35-repeat-pass.xml`; logs are
|
||||
`upstream-integration-final-retry.log` and `upstream-integration-repeat.log`.
|
||||
These files are local evidence, not published
|
||||
artifacts or a hosted CI result.
|
||||
|
||||
Test environment: JDK 17.0.20.1, Node 22.22.1, Python 3.14.4, Android Emulator
|
||||
37.2.12, API 35 x86_64 Google APIs image, WebView 124.0.6367.219. The old bundled
|
||||
WebView is useful compatibility evidence, not a recommendation to use an unpatched
|
||||
engine; a current engine/device run remains mandatory.
|
||||
|
||||
## Artifacts
|
||||
|
||||
Ignored `artifacts/android/` contains the development-signed debug APK and unsigned
|
||||
release APK/AAB, `SHA256SUMS`, `build-info.json` and manifest/policy/signature
|
||||
inspection evidence. No integration APK is collected. No IPA or Apple archive
|
||||
exists. See [Android build](build-android.md) for repeatable collection commands.
|
||||
|
||||
## Commands
|
||||
|
||||
```sh
|
||||
bash android/gradlew -p android testDebugUnitTest lintDebug lintRelease assembleDebug assembleRelease bundleRelease connectedDebugAndroidTest
|
||||
python3 scripts/test-integration.py /path/to/pinned-upstream --android
|
||||
swift test --package-path ios
|
||||
swiftc -frontend -parse ios/Sources/*.swift ios/Tests/*.swift ios/UITests/*.swift
|
||||
python3 scripts/check-repository.py
|
||||
python3 scripts/check-dependencies.py
|
||||
python3 scripts/test-verifier.py
|
||||
python3 scripts/collect-android-artifacts.py
|
||||
git diff --check
|
||||
```
|
||||
|
||||
This environment is Linux/WSL. Android SDK and a KVM emulator were installed for
|
||||
real execution. Build output relocation was needed because the Windows mount
|
||||
rejects some Gradle POSIX metadata operations. Swift's Linux toolchain was
|
||||
installed for portable tests. No macOS, Xcode, Apple simulator or physical device
|
||||
is available; no iOS build/archive/UI result is claimed.
|
||||
|
||||
## Mandatory remaining evidence
|
||||
|
||||
- Run Xcode build, XCTest/UI tests and unsigned archive on macOS; fix any compiler
|
||||
or runtime issues. The app has **not** yet been typechecked against Apple SDKs.
|
||||
- Validate real IdPs: cancellation, account linking, TOTP after OIDC, and embedded
|
||||
provider policy. Browser-only providers have no native-session handoff upstream.
|
||||
- Real-device camera/document picker cancellation, file MIME cases, rotation with
|
||||
an outstanding picker, network loss/reconnect, process kill/memory pressure,
|
||||
session expiry/revocation, OS backup, and offline account isolation.
|
||||
- Android 17 private-network permission grant/denial/revocation on a matching OS.
|
||||
Also run minimum-supported API 26 and a current OS/WebView device matrix.
|
||||
- VoiceOver/TalkBack, large text, contrast, keyboard/safe areas, reduced motion,
|
||||
light/dark appearance and responsive web modules on actual supported devices.
|
||||
- Successful CI runs on the configured Gitea runners, private security
|
||||
reporting contact, human security review, store ownership and production signing.
|
||||
|
||||
No Firebase/APNs registration, closed-app push, offline editing, App Store approval,
|
||||
signing, publication or physical-device validation is claimed. See `SECURITY.md`
|
||||
and `docs/security-review.md` for residual limitations.
|
||||
Resume work using [maintainer continuation](continuation.md).
|
||||
|
||||
## Gitea runner adaptation
|
||||
|
||||
Workflows now live in `.gitea/workflows/` and target the supplied `ubuntu-latest`
|
||||
pool and native `macos-arm64` M4 Pro runner. Local workflow grammar lint (Gitea URL
|
||||
syntax normalized), repository invariants, shell/Python syntax, ten mocked runner
|
||||
preflight regressions and eight evidence-verifier regressions pass. SHA-256 Git
|
||||
initialization/fetch was exercised locally; the pinned XcodeGen archive's checksum
|
||||
and native arm64 slice were verified. These are not remote runner execution or
|
||||
Apple SDK results. See [runner requirements](ci-runners.md); the local emulator
|
||||
preflight currently rejects unavailable/inaccessible KVM as designed. Original
|
||||
application build evidence above remains historical and is not a rebuild of the
|
||||
workflow-only changes.
|
||||
@@ -0,0 +1,81 @@
|
||||
# YUVOMI MOBILE – FINAL DELIVERY REPORT
|
||||
|
||||
**Delivery status: incomplete native preview, not final product acceptance.**
|
||||
This report closes the initial native rebuild slice, not the requested complete
|
||||
1:1 replacement. No module has accepted functional and visual parity.
|
||||
|
||||
## 1. Outcome
|
||||
|
||||
The rejected embedded-browser application has been replaced by genuine native
|
||||
shipping entry points. Missing modules do not fall back to a WebView.
|
||||
|
||||
## 2. Upstream reference
|
||||
|
||||
Unmodified Yuvomi 2.78.0, commit
|
||||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`. No upstream change or push.
|
||||
|
||||
## 3. Android
|
||||
|
||||
Kotlin/Compose onboarding, setup/password/TOTP interfaces, basic dashboard,
|
||||
tasks/notes/shopping and session management. Version `0.2.0-native-preview`,
|
||||
code 2. This is a tested initial slice, not full module coverage.
|
||||
|
||||
## 4. iOS
|
||||
|
||||
SwiftUI equivalents, native API models/transport and Keychain storage implemented.
|
||||
Sixteen portable tests pass; Apple SDK application/UI/Keychain validation remains
|
||||
unverified locally. No installable IPA or App Store-ready archive is claimed.
|
||||
|
||||
## 5. Design parity
|
||||
|
||||
Upstream colors, spacing/radii and brand geometry guide native controls. One real
|
||||
synthetic Android dashboard screenshot was inspected. No side-by-side full PWA
|
||||
visual acceptance, complete adaptive-layout or accessibility approval yet.
|
||||
|
||||
## 6. API and architecture
|
||||
|
||||
Direct same-origin HTTPS/JSON, native controls and state; server-owned business
|
||||
logic and authorization. Superseded browser code/tests are preserved in `legacy/`
|
||||
but excluded from shipping builds and native test counts.
|
||||
|
||||
## 7. Security
|
||||
|
||||
System TLS, redirect refusal, bounded reads, upstream CSRF and protected native
|
||||
cookies. AndroidKeyStore/AES-GCM and iOS Keychain/private URLSession storage; no
|
||||
stored passwords, test CA in ordinary builds or hidden browser session import.
|
||||
Human security review and additional device/role/error-path coverage remain open.
|
||||
|
||||
## 8. Executed validation
|
||||
|
||||
10 JVM tests, 6 native API-35 UI tests, the 7-test real-server suite (including
|
||||
those same 6), both Android lint variants and package builds pass. Swift has 16
|
||||
portable passes plus strict formatting/parsing. 23 script regressions, repository
|
||||
checks, workflow lint and the 266-coordinate OSV scan pass. See
|
||||
[validation](validation.md) for evidence, failures corrected and exact limitations.
|
||||
|
||||
## 9. Artifacts
|
||||
|
||||
The local collector replaces old wrapper outputs in ignored `artifacts/android/`
|
||||
with native debug APK and unsigned release APK/AAB, checksums and manifest/network/
|
||||
signature inspection. `build-info.json` records exact source identity and dirty
|
||||
state. Only the development-signed debug APK is installable as provided.
|
||||
|
||||
## 10. Gitea CI
|
||||
|
||||
The Android workflow offers `android-native-debug-apk`; the Mac workflow bootstraps
|
||||
verified ARM64 Node before checkout. Actual artifact publication and Apple build
|
||||
results require remote-run inspection. Remote Ubuntu emulator jobs need KVM access;
|
||||
local emulator success is not a substitute for a passing remote matrix.
|
||||
|
||||
## 11. Signing and publication
|
||||
|
||||
Initial owner-authorized signing material/secrets are preserved privately; signing
|
||||
workflow changes remain parked in the named stash. No production-signed native
|
||||
release, store submission or claim of completed product delivery.
|
||||
|
||||
## 12. Remaining work
|
||||
|
||||
Native SSO/recovery/invitations, advanced first-slice controls, the remaining
|
||||
modules/settings, files, offline, notifications, Apple/device validation and 1:1
|
||||
visual/behavior acceptance remain substantial work. The complete page inventory
|
||||
and acceptance criteria are in [native parity](native-parity.md).
|
||||
@@ -0,0 +1,91 @@
|
||||
# Native parity tracker
|
||||
|
||||
## Acceptance contract
|
||||
|
||||
**Native means native screens, forms, lists, navigation and interaction.** Android
|
||||
uses Kotlin/Compose; iOS uses SwiftUI. PWA HTML/JavaScript is not embedded as the
|
||||
application surface. The PWA is the design/behavior reference, not the renderer.
|
||||
|
||||
Reference: unmodified upstream 2.78.0,
|
||||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`. The scope includes its thirty page
|
||||
modules, settings leaves, permissions, dashboard customization and cross-module
|
||||
workflows. Third-party web extensions need an explicit native integration design;
|
||||
arbitrary server-installed HTML cannot silently become a native module.
|
||||
|
||||
Use these states honestly:
|
||||
|
||||
- **Slice**: real native UI/API interaction exists, with the listed limitations.
|
||||
- **Pending**: not implemented. No fake screen, raw-JSON editor or WebView fallback.
|
||||
- **Parity accepted**: requires functional and visual evidence on both platforms.
|
||||
**No module currently has this status.**
|
||||
|
||||
## Page inventory
|
||||
|
||||
| Upstream page | Native status | Work still required before parity |
|
||||
| --- | --- | --- |
|
||||
| login | Slice: password + TOTP/recovery step | OIDC/provider policy, recovery/error UX, localization, visual comparison |
|
||||
| setup | Slice: initial household creation | Full onboarding and configuration workflow |
|
||||
| forgot-password | Pending | Native recovery request and server-capability UX |
|
||||
| reset-password | Pending | Native reset token/confirmation flow |
|
||||
| join | Pending | Invitations, account setup, validation |
|
||||
| dashboard | Slice: task/calendar/shopping/note previews | All remaining widgets, user layout/options, timezone-aware presentation, quick add, wall mode |
|
||||
| tasks | Slice: list/search/status filter/create/edit/complete/delete | Category/assignee/tag/visibility controls, recurrence, subtasks, attachments, comments, archive/history, lock UX, bulk/sync controls |
|
||||
| shopping | Slice: lists/items/create/edit/check/delete | List rename/duplicate, categories, ordering, suggestions, live versions, prices/stores, imports/send/undo |
|
||||
| notes | Slice: list/search/create/edit/pin/delete | Markdown/checklists, categories, note colors, ordering and concurrent edit UX |
|
||||
| calendar | Dashboard preview only; module pending | Agenda/week/month, editing, recurrence/scopes, source calendars, timezone behavior, attachments/sync |
|
||||
| schedule | Pending | Shift grid, roster, creation and settings |
|
||||
| birthdays | Pending | Date/age privacy, contacts, reminders/import |
|
||||
| contacts | Pending | Address book, editing, links/import/export |
|
||||
| documents | Pending | Browse/search, metadata, native upload/camera/export and lifecycle tests |
|
||||
| inventory | Pending | Items, locations, guarantees, attachments and reminders |
|
||||
| meals | Pending | Meal plan, ingredients, household options and shopping transfer |
|
||||
| recipes | Pending | Search/detail/editor, source import, images, pantry/shopping cross-links |
|
||||
| pantry | Pending | Stock, batches/expiry, locations, quantity controls and shopping transfer |
|
||||
| budget | Pending | Accounts, entries, categories, currency/amount handling and attachments |
|
||||
| budget-plans | Pending | Plan editor, period/category matching and forecasts |
|
||||
| budget-stats | Pending | Native charts and filters matching upstream calculations |
|
||||
| subscriptions | Pending | Lifecycle, billing, recurrence and linked budget behavior |
|
||||
| split-expenses | Pending | Groups, guests, balances, settlement and permission distinctions |
|
||||
| housekeeping | Pending | Visits, tasks, time and role-gated payment data |
|
||||
| waste | Pending | Schedules, pickup display/import and reminders |
|
||||
| rewards | Pending | Catalog, ledger, goals, approvals and pocket-money precision |
|
||||
| health | Pending | Medication, cycle, nutrition and capability-gated private views |
|
||||
| health-fasting | Pending | Clock, history, capabilities and lifecycle behavior |
|
||||
| settings | Slice: native logout/server removal only | Every relevant personal/admin settings leaf and native permissions |
|
||||
| pair-display | Pending | Pairing protocol, display role and shared-surface privacy |
|
||||
|
||||
## Design reference
|
||||
|
||||
Native primitives reuse the upstream warm palette (`#F5F3ED` / `#191816`), opaque
|
||||
surfaces (`#FFFFFF` / `#2B2825`), violet accent, 16-point cards, 26-point auth panel,
|
||||
pill navigation/buttons and the exact three-circle brand geometry. These are
|
||||
initial design-token mappings, **not proof of 1:1 visuals**. Material/SF symbols,
|
||||
typography, sheets, adaptive layouts and module details still need comparison.
|
||||
|
||||
Every accepted module needs side-by-side screenshots from matching server data,
|
||||
light/dark and small/large text coverage, keyboard/safe-area/back behavior,
|
||||
read-only/denied permission cases and real API success/error tests. Android's
|
||||
integration test exports a synthetic-fixture native dashboard screenshot; it is
|
||||
not a production screenshot or a visual-parity approval.
|
||||
|
||||
## Implementation order
|
||||
|
||||
1. Stabilize the current native authentication/dashboard/tasks/notes/shopping
|
||||
slice, including Apple SDK compilation and actual native tests.
|
||||
2. Close auth/recovery/SSO and first-slice feature gaps, then accept those screens
|
||||
against PWA visual/behavior baselines rather than adding empty menu entries.
|
||||
3. Implement calendar/family/contacts, kitchen/pantry, documents/inventory, then
|
||||
finance, household, rewards and health as separately tested native slices.
|
||||
4. Complete settings, extensions/cross-module flows, accessibility, offline and
|
||||
notifications. Audit every upstream route/settings leaf before claiming parity.
|
||||
|
||||
## Signing work retained, not released
|
||||
|
||||
The owner-authorized initial signing key and four Gitea repository secrets were
|
||||
created before the native correction. The private backup remains outside Git at
|
||||
`/home/neste/yuvomi-signing/initial-20261021`. Never print/commit its contents.
|
||||
The uncommitted signing-workflow changes were preserved in Git stash
|
||||
`wip: owner-authorized signing setup paused for true native rewrite`; do not apply
|
||||
it blindly to the new workflows. No signing-secret values belong in screenshots,
|
||||
test fixtures, documentation, commits or artifacts. Native signing/release work
|
||||
remains paused until this preview's scope is explicitly accepted.
|
||||
@@ -10,14 +10,14 @@ to either store. A debug APK or unsigned archive is not a production release.
|
||||
a provisional community identifier, not proof of registry/store ownership.
|
||||
Confirm use of the Yuvomi name, required attribution and independent status.
|
||||
3. Bump version/name/code in Android and the iOS project spec; update CHANGELOG.
|
||||
4. Run JVM/emulator/real-upstream HTTPS tests, portable Swift and Xcode simulator
|
||||
4. Run native JVM/Compose/emulator/real-upstream HTTPS tests, portable Swift and Xcode simulator
|
||||
tests, static checks, OSV scan, release builds and artifact inspection. Record
|
||||
upstream revision, app SHA, OS/WebView/Xcode versions, results and checksums.
|
||||
upstream revision, app SHA, OS/SDK/Xcode versions, results and checksums.
|
||||
5. Produce signed artifacts only using an authorized maintainer's credentials.
|
||||
6. Review store privacy/Data Safety answers for the app AND selected-server model,
|
||||
permission rationale, encryption/export compliance, screenshots, support URL,
|
||||
vulnerability contact, and device demonstrations. A functional web companion
|
||||
is not guaranteed to pass Apple's minimum-functionality review.
|
||||
vulnerability contact, and device demonstrations. An incomplete native preview
|
||||
is not a finished PWA replacement or App Store approval.
|
||||
7. Create a release/tag and publish artifacts/store submissions manually only
|
||||
after explicit maintainer authorization. Never force-push or rewrite history.
|
||||
|
||||
@@ -31,7 +31,10 @@ An authorized maintainer must separately sign the verified APK/AAB using their
|
||||
own keystore, alias and passwords with `zipalign`, `apksigner`, and `jarsigner`.
|
||||
Keep private material in a protected signing environment, never on the general
|
||||
validation runners. Securely back up the real upload key and use Play App Signing
|
||||
according to the owner's policy. No production key is generated here.
|
||||
according to the owner's policy. An initial owner-authorized key and repository
|
||||
secrets already exist outside Git; signing workflow changes are parked during
|
||||
the native rebuild. Preserve the key, do not generate a replacement or apply the
|
||||
old signing stash without review. See `native-parity.md`.
|
||||
Manually verify APK/AAB signatures and inspect
|
||||
the final manifest: no debuggable flag, HTTP/test CA or unintended exported component.
|
||||
Never distribute an `.integration` package or include its generated test resources.
|
||||
|
||||
+31
-42
@@ -1,47 +1,36 @@
|
||||
# Security review record
|
||||
# Native security review record
|
||||
|
||||
This is an engineering review, not an independent penetration test or certification.
|
||||
This is an engineering checklist, not an independent audit or release approval.
|
||||
The wrapper review is retained separately as
|
||||
[historical evidence](legacy-wrapper-security-review.md).
|
||||
|
||||
Addressed during implementation:
|
||||
## Implemented controls to exercise
|
||||
|
||||
- Canonical, HTTPS-only origin/port comparison; credential, fragment, query,
|
||||
subpath, scheme, lookalike-host and TLS-downgrade regression cases.
|
||||
- A main-frame POST can bypass Android's usual navigation callback. The request
|
||||
interception gate now rejects **all** cross-origin requests, not only subresources.
|
||||
The emulator regression was observed failing when the main-frame guard was
|
||||
deliberately removed, then rerun with the fix restored.
|
||||
- TLS failures cancel by default. Native download redirects are refused before
|
||||
cookies can be replayed to another origin. Bootstrap requests use neither
|
||||
cookies nor automatic redirects and have bounded metadata reads/timeouts.
|
||||
- Files use explicit system selection/content URIs; no filesystem or storage
|
||||
permission is granted to web content. Blob exports have no native JS bridge.
|
||||
- Complete Android browsing-data deletion uses WebStorageCompat, with OS app
|
||||
reset for engines without that capability. WebStorage.deleteAllData alone was
|
||||
insufficient for service-worker CacheStorage/IndexedDB and is not relied upon.
|
||||
- iOS server erase replaces the WKWebView, not only its URL, eliminating old
|
||||
history/back-forward contexts as well as persistent website data.
|
||||
- iOS metadata uses typed decoding, rejecting numeric values masquerading as booleans.
|
||||
- Native picker results are bound to the browsing generation/request. Android
|
||||
rejects stale upload/download selections, revokes camera URI grants, and clears
|
||||
capture cache on erasure. iOS ignores export-cancellation callbacks from an old
|
||||
download. Apple-specific callback regressions have not run without Xcode.
|
||||
- KGP was upgraded after OSV identified CVE-2026-53914 in the original build tool.
|
||||
The final OSV scan found no listed advisories across 213 locked/direct Maven
|
||||
coordinates and build plugins. Rescan after resolution/lock updates.
|
||||
- The inspected release APK is not debuggable, rejects cleartext, disables backup
|
||||
and trusts system CAs only. AndroidX's exported profile installer receiver is
|
||||
protected by the system DUMP permission; app providers are not exported.
|
||||
- Origin-bound HTTPS API transports, no redirects, no production test-CA bypass.
|
||||
- Server-owned session and CSRF semantics, no persistent password storage.
|
||||
- Origin-bound AES-GCM/AndroidKeyStore cookies; iOS Keychain protected
|
||||
WhenUnlockedThisDeviceOnly with a private ephemeral URLSession jar.
|
||||
- Bounded JSON reads, deadlines and no offline/ambiguous-write retry queue.
|
||||
- Native permission-aware controls, destructive-action confirmation and server
|
||||
validation; partial update payloads preserve fields the native editor cannot edit.
|
||||
- No WebView/WKWebView in either shipping source tree. Legacy tests do not prove
|
||||
this client's behavior; explicit native tests and source invariants are required.
|
||||
|
||||
Release gates still requiring evidence:
|
||||
## Remaining gates
|
||||
|
||||
- Actual Xcode typecheck, simulator, archive, physical-device and accessibility review.
|
||||
- End-to-end IdP flows, especially providers that prohibit embedded agents; no
|
||||
browser-to-native session transfer is supported by the current upstream protocol.
|
||||
- iOS unknown-length download disk-pressure behavior; a post-download size check
|
||||
is not a streaming quota. Verify file picker/camera cancellation on real devices.
|
||||
- Android file-picker/camera/rotation while a picker is outstanding; cancellation
|
||||
on process death intentionally loses the selection, never silently retries it.
|
||||
- Offline sign-out/account switching, stale-worker updates and server erasure on
|
||||
current WebView/WKWebView versions. Upstream tests are not native device proof.
|
||||
- Reverify final signed release manifests, signing, store ownership, private vulnerability contact
|
||||
and applicable privacy disclosures. No claim that all vulnerabilities are absent.
|
||||
1. Run Apple SDK typechecking, simulator/XCTest/UI and device checks; portable
|
||||
Foundation transport compilation is not SwiftUI/Security.framework validation.
|
||||
2. Review persistent-cookie expiry/removal, TLS failures, redirects, CSRF refresh,
|
||||
expired sessions, background/recreation and stale-response isolation on devices.
|
||||
3. Review migrations from the prototype: browser sessions are never imported and
|
||||
OS website data may remain until app-data reset/reinstall.
|
||||
4. Complete missing auth/provider protocols and permission/role scenarios before
|
||||
claiming native authentication parity, particularly SSO-only deployments.
|
||||
5. Implement/review files, notifications, offline storage and additional modules
|
||||
as actual native capabilities; do not restore the wrapper as a shortcut.
|
||||
6. Independently review the new UI/state/transport code, actual signed artifacts,
|
||||
accessibility, supported OS matrix and runner trust before distribution.
|
||||
|
||||
The owner-authorized signing configuration exists privately but its workflow
|
||||
changes are intentionally parked. A signed incomplete client is not a completed
|
||||
native product. Refer to [native parity](native-parity.md) before release work.
|
||||
@@ -1,70 +1,41 @@
|
||||
# Server compatibility and authentication
|
||||
# Native server compatibility
|
||||
|
||||
Source reference: upstream 2.78.0 revision
|
||||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`. No general version range has been
|
||||
certified. Anonymous bootstrap metadata deliberately omits the exact version;
|
||||
native probing verifies shape, not an invented minimum-version comparison.
|
||||
Reference: Yuvomi 2.78.0 at
|
||||
`10bfef7686ed7303b4c74c7fcc55a5eb16356c9d`. No general server-version range or
|
||||
complete native feature compatibility is certified.
|
||||
|
||||
Use `https://family.example.com` or `https://family.example.com:8443`, backed by a
|
||||
root-hosted Yuvomi installation and a valid system-trusted certificate. Operators
|
||||
should set `SESSION_SECURE=true`, correct `BASE_URL`, and correct proxy trust.
|
||||
Private servers are supported through reachable HTTPS/VPN, not TLS bypasses.
|
||||
International hostnames should be entered in ASCII/punycode for both platforms.
|
||||
Enter a root HTTPS hostname, optionally with a custom port. HTTP, embedded
|
||||
credentials, query/fragment configuration and subpath deployments are rejected.
|
||||
Use a valid system-trusted TLS certificate and reachable VPN/LAN connectivity.
|
||||
No certificate bypass or proprietary mobile service is introduced.
|
||||
|
||||
Root-relative assets, API endpoints, cookie paths, callback redirects and worker
|
||||
registration mean `/yuvomi/` subpaths are not supported by the inspected source.
|
||||
Use a dedicated hostname. Reverse proxies must pass `/api/v1/*`, cookies, HTML,
|
||||
JavaScript and the service worker consistently. An external authentication proxy
|
||||
that intercepts bootstrap calls is rejected with a connection error; it is not
|
||||
silently identified as a Yuvomi server.
|
||||
The native client probes the real public `/api/v1/version` and
|
||||
`/api/v1/auth/oidc/config` shapes. Anonymous metadata does not disclose the server
|
||||
version. An authentication proxy returning redirects/HTML instead of those JSON
|
||||
contracts is unsupported, not silently treated as a valid Yuvomi API.
|
||||
|
||||
## Authentication
|
||||
|
||||
Password login, TOTP/recovery codes, password reset, invitations, server-side
|
||||
session expiry/revocation and logout remain upstream web flows. No native code
|
||||
stores the password, supplies a CSRF bypass, or extends an expired session.
|
||||
Backgrounding does not clear cookies. Native server erasure does not revoke a
|
||||
remote session; use Yuvomi logout first or revoke sessions server-side.
|
||||
The implemented native slice uses setup/password login, the existing two-factor
|
||||
verification endpoint, `/auth/me`, session cookies, CSRF headers and logout.
|
||||
Passwords are not stored. Native session persistence is separate from browser
|
||||
storage and protected by the platform keystore/keychain.
|
||||
|
||||
### OIDC: local fixture verified; real-provider validation pending
|
||||
**Native SSO is not implemented yet.** The old wrapper's local-IdP WebView result
|
||||
does not apply to this client. The existing server protocol does not provide a
|
||||
generic browser-to-native session exchange for arbitrary self-hosted hosts; a
|
||||
reviewed solution is required. SSO-only deployments cannot currently use this
|
||||
native preview. Reset and invitation workflows also remain pending.
|
||||
|
||||
The initiating Yuvomi session contains OIDC state, nonce and PKCE verifier. When
|
||||
the server redirects to an identity provider, native consent offers an isolated
|
||||
web sign-in window sharing the OS website cookie store. HTTPS-only redirects
|
||||
can return to the server callback; the final same-origin page returns to the main
|
||||
view. No app-capability handlers or JS bridge are installed in that auth window.
|
||||
Only initial dashboard/tasks/notes/shopping capabilities are implemented; see the
|
||||
[parity tracker](native-parity.md) for precise gaps. The complete server UI is not
|
||||
embedded to fill those gaps. Read-only and denied module permissions affect
|
||||
native controls; the server remains the enforcement point.
|
||||
|
||||
Some providers (including configurations that prohibit embedded user agents)
|
||||
require a system browser. **Those cannot sign the native view in with upstream's
|
||||
current protocol.** Use Server settings -> Open server in browser, and sign in
|
||||
there for an independent browser session. Opening only the external authorization
|
||||
link in a browser does not transfer the initiating cookie. Browser cookies are
|
||||
never copied into the app, and custom-scheme callbacks are not fabricated.
|
||||
## Notifications, files and offline
|
||||
|
||||
The API 35 integration suite completes a native isolated-window round trip with
|
||||
a local test IdP, real RS256 ID tokens, nonce and S256 PKCE. No external
|
||||
IdP/developer account was supplied. Validate the actual provider, including
|
||||
cross-site cookies, cancellation, errors, TOTP and account linking, before relying
|
||||
on that deployment. iOS authentication has not run against Apple SDKs. A native
|
||||
browser handoff would require an independently reviewed upstream protocol; no
|
||||
such upstream change is included or published.
|
||||
|
||||
Android generated exports require a current WebView supporting document-start
|
||||
scripts and are capped at 25 MB. A bounded Blob registry preserves a generated
|
||||
file even when upstream immediately revokes its object URL; it does not fetch
|
||||
blob URLs or alter the server's CSP. HTTPS file downloads are capped at 100 MB.
|
||||
Update the system WebView if generated exports are unavailable on an old engine.
|
||||
|
||||
## Notifications and offline
|
||||
|
||||
Upstream implements Web Push and optional ntfy/Gotify/webhook/email channels.
|
||||
Embedded web views do not supply a portable native push subscription. This app
|
||||
has **no native remote-push claim**, no Firebase/APNs secrets, no background
|
||||
polling service, and no fake notification-registration UI. Configure an existing
|
||||
optional upstream ntfy/Gotify channel and its client if desired. No centralized
|
||||
service is required by this application.
|
||||
|
||||
Upstream service-worker caching is read-only, allow-listed, and versioned.
|
||||
Mutations/authentication remain online. Platform-specific cache/resume behavior
|
||||
and offline account switching still need device validation. Do not rely on offline
|
||||
editing, synchronization, or closed-app push in this native development build.
|
||||
Native remote push, uploads/camera/download/export and offline caching/editing
|
||||
are not current native capabilities. The old wrapper's file handlers and the
|
||||
PWA service worker are not part of the native renderer. No fake registration or
|
||||
automatic offline mutation replay is supplied. Optional existing server-side
|
||||
ntfy/Gotify/email integrations remain independently operated upstream features.
|
||||
+58
-119
@@ -1,92 +1,60 @@
|
||||
# Validation status
|
||||
# Native validation
|
||||
|
||||
**Partially verified development software, not production-ready.**
|
||||
Local validation date: 2026-10-21. No unexecuted iOS application test, hosted CI
|
||||
run, production signing, or store publication is represented as completed.
|
||||
**Incomplete native rebuild; not full PWA parity and not production-ready.**
|
||||
The old browser results are [historical only](legacy-wrapper-validation.md).
|
||||
|
||||
## Executed evidence
|
||||
The new shipping surfaces are Android Compose and iOS SwiftUI. Current native
|
||||
tests are in `androidTestNative` / `androidTestNativeIntegration`, JVM native policy
|
||||
tests, and Swift production contracts/transport tests. Archived WebView tests are
|
||||
not included in the native suites or counted toward native completion.
|
||||
|
||||
- Android debug APK and unsigned release APK/AAB built successfully; both
|
||||
`lintDebug` and `lintRelease` passed. JVM security/picker-policy tests: **7 passed,
|
||||
zero failures/skips**.
|
||||
- Android API 35 regular emulator suite: **6 passed, zero failures/skips**.
|
||||
This covers onboarding, invalid URLs, background/resume, hardened settings,
|
||||
cross-origin POST/subresource isolation, opaque-page Blob rejection and activity
|
||||
recreation. Its permission test checks that the API 37 permission UI is absent;
|
||||
it is **not** evidence of API 37 permission grant/denial behavior.
|
||||
- Unmodified pinned upstream ran behind a temporary HTTPS reverse proxy.
|
||||
Bootstrap metadata, password login, Secure/HttpOnly/SameSite cookies, persistent
|
||||
session, CSRF rejection, logout/revocation passed in the harness.
|
||||
- Android's extended real-server scenario exercises login, HttpOnly cookies,
|
||||
document upload via upstream fetch, native FileTransfer output, bounded Blob
|
||||
export, background/resume, recreation, CSRF-protected logout, revocation,
|
||||
recovery, isolated OIDC return and back navigation. It does not automate the OS
|
||||
camera/document destination picker or prove every upstream module works.
|
||||
Two consecutive API 35 runs have **7 passed, zero failures/skips each**, including the
|
||||
six regular security/onboarding cases and this real-server scenario.
|
||||
- The cross-origin POST regression was deliberately observed failing without its
|
||||
guard. The production guard was restored and the API 35 regression passes.
|
||||
- Portable Swift production-policy tests: 7 passed (URL and typed metadata).
|
||||
All Swift sources passed format lint and parsing with Swift 6.2.1 on Linux.
|
||||
The portable package excludes BrowserModelTests. This does not build iOS.
|
||||
- Selected upstream suites ran successfully: cookie-secure-flag (4),
|
||||
session-sliding (8), two-factor (22), password-reset (24), sw-api-cache (42).
|
||||
Upstream's plain OIDC script also exited successfully. These are upstream tests,
|
||||
not evidence of a provider round-trip or native push support.
|
||||
- The HTTPS harness independently passed upstream OIDC discovery, RS256 ID-token
|
||||
signature/nonce validation, S256 PKCE exchange and session creation with a local
|
||||
test IdP. The fixture checks single-use codes, exact redirect URIs and OAuth
|
||||
Basic client authentication. Loopback hosts/ports and automatic fixture consent
|
||||
are not representative of every provider's cross-site/embedded-agent policies.
|
||||
- OSV: no listed advisories for **213** locked/direct Maven coordinates and build
|
||||
plugins at scan time. This is not a guarantee that no vulnerabilities exist.
|
||||
- ktlint 1.7.1, actionlint 1.7.7, repository invariants, Python compilation,
|
||||
Node syntax and shell syntax checks passed. JUnit-verifier regression suite:
|
||||
**8 passed**, including rejection of absent, empty, malformed, insufficient,
|
||||
failed, errored and skipped evidence.
|
||||
- Release APK inspection confirms API 26 minimum / API 37 target, no debuggable
|
||||
flag, backups and cleartext disabled, system-only certificate trust. Exported
|
||||
entry points are the launcher and AndroidX ProfileInstallReceiver protected by
|
||||
the system DUMP permission; file/startup providers are not exported. Debug APK
|
||||
signature verifies; release APK/AAB are unsigned. Collected archives contain no
|
||||
fixture CA/key or signing-key files.
|
||||
## Executed locally — 2026-10-21
|
||||
|
||||
## Emulator limitations and retry evidence
|
||||
| Check | Observed result |
|
||||
| --- | --- |
|
||||
| Android JVM tests | 10 passed; zero failed/skipped |
|
||||
| Native Compose UI/security suite, API 35 emulator | 6 passed; zero failed/skipped |
|
||||
| Real-upstream native integration suite | 7 passed; zero failed/skipped (the same 6 onboarding tests plus 1 multi-step real-server scenario) |
|
||||
| Native scenario | Login/dashboard, activity recreation, task/note/list/item creation and API readback, redirect refusal, logout and vault erasure |
|
||||
| Integration screenshot export | Successful AGP test-output collection; native dashboard PNG opened and visually confirmed nonblank, synthetic data only |
|
||||
| Android lint | Debug and release passed; newer-version recommendations remain informational |
|
||||
| Android packages | Debug APK and unsigned release APK/AAB built successfully |
|
||||
| Swift portable suite | 16 passed; actual Foundation transport/contracts and URL/metadata policy, not Apple UI/Keychain execution |
|
||||
| Swift formatting/parsing | Strict format lint and parsing passed, including Apple-only sources |
|
||||
| Script regressions | 10 runner-preflight, 8 JUnit-evidence and 5 screenshot-output tests passed |
|
||||
| Repository/workflows | Source invariants, Python compilation, diff whitespace and actionlint for all 3 Gitea workflows passed |
|
||||
| OSV | No listed advisories for 266 locked/direct Maven coordinates and plugins; not a security audit |
|
||||
|
||||
Earlier extended-suite attempts crashed the host emulator with SIGSEGV under
|
||||
software/off GPU modes. Host-GPU mode remained running and produced actionable
|
||||
JUnit failures: an OIDC-return synchronization timeout, followed by an outage
|
||||
assertion that incorrectly assumed the upstream worker could not serve its cached
|
||||
app shell, then a document-readiness race after recreation. Tests now verify the
|
||||
loaded JavaScript origin, wait for the sign-in window to close, retry only a probe
|
||||
lost to document replacement and exercise recovery through uncached metadata.
|
||||
The completed retry passes all seven tests without disabling the worker or
|
||||
weakening production TLS/CSP/origin policies.
|
||||
Environment: Linux/WSL, OpenJDK 17.0.20.1, Gradle 9.6.0, AGP 9.4.1,
|
||||
Kotlin/Compose compiler 2.4.21, API 35 `sdk_gphone64_x86_64` emulator, Swift 6.2.1.
|
||||
The host-only Tink upgrade to 1.15.0 removes the observed obsolete generated
|
||||
protobuf warning; the final Android validation log has no such warning.
|
||||
|
||||
API 37 attempts encountered broken package/activity services and locked
|
||||
credential-encrypted storage. **No API 37 runtime pass is claimed.**
|
||||
The first integration attempt missed the scrolled-off login button. Later,
|
||||
post-uninstall screenshot retrieval failed, and the first compositor capture was
|
||||
black. The final test scrolls the real button, uses native-window capture with a
|
||||
nonblank-pixel assertion and writes through `PlatformTestStorageRegistry` for AGP
|
||||
collection. The latest complete harness exits successfully, not just its JUnit
|
||||
subprocess. Ordinary builds retain screenshot protection.
|
||||
|
||||
Local logs and reports live in `/home/neste/yuvomi-build/`; test XML is under
|
||||
`app/outputs/androidTest-results/connected/`. Earlier failing JUnit snapshots are
|
||||
preserved as `integration-host-gpu-oidc-race.xml` and
|
||||
`integration-host-gpu-sw-cache.xml`, plus
|
||||
`integration-host-gpu-document-ready.xml`. Passing evidence is preserved in
|
||||
`integration-api35-first-pass.xml` and `integration-api35-repeat-pass.xml`; logs are
|
||||
`upstream-integration-final-retry.log` and `upstream-integration-repeat.log`.
|
||||
These files are local evidence, not published
|
||||
artifacts or a hosted CI result.
|
||||
The unmodified pinned upstream HTTPS/OIDC protocol fixture also passed TLS trust,
|
||||
metadata, cookies, CSRF and remote revocation checks. Its IdP exchange is **not
|
||||
native SSO**: the native client refuses the redirect and SSO remains pending.
|
||||
|
||||
Test environment: JDK 17.0.20.1, Node 22.22.1, Python 3.14.4, Android Emulator
|
||||
37.2.12, API 35 x86_64 Google APIs image, WebView 124.0.6367.219. The old bundled
|
||||
WebView is useful compatibility evidence, not a recommendation to use an unpatched
|
||||
engine; a current engine/device run remains mandatory.
|
||||
Evidence paths in the local external build directory:
|
||||
|
||||
## Artifacts
|
||||
- `app/test-results/testDebugUnitTest/`
|
||||
- `app/outputs/androidTest-results/connected/{debug,integration}/`
|
||||
- `app/outputs/native-screenshots/native-dashboard.png`
|
||||
- `app/reports/lint-results-{debug,release}.html`
|
||||
- Logs: `/home/neste/yuvomi-native-validation.log`,
|
||||
`/home/neste/yuvomi-native-integration-final.log`,
|
||||
`/home/neste/yuvomi-native-swift.log`.
|
||||
|
||||
Ignored `artifacts/android/` contains the development-signed debug APK and unsigned
|
||||
release APK/AAB, `SHA256SUMS`, `build-info.json` and manifest/policy/signature
|
||||
inspection evidence. No integration APK is collected. No IPA or Apple archive
|
||||
exists. See [Android build](build-android.md) for repeatable collection commands.
|
||||
No Apple SDK application build, simulator UI test or physical-device result is
|
||||
claimed from these Linux runs. The modified Mac bootstrap and remote APK upload
|
||||
still require inspection of the next actual Gitea run. Prior remote emulator jobs
|
||||
failed KVM preflight; the prerequisite was not weakened or counted as passing.
|
||||
|
||||
## Commands
|
||||
|
||||
@@ -97,47 +65,18 @@ swift test --package-path ios
|
||||
swiftc -frontend -parse ios/Sources/*.swift ios/Tests/*.swift ios/UITests/*.swift
|
||||
python3 scripts/check-repository.py
|
||||
python3 scripts/check-dependencies.py
|
||||
python3 scripts/test-verifier.py
|
||||
python3 scripts/collect-android-artifacts.py
|
||||
git diff --check
|
||||
python3 scripts/lint-workflows.py /path/to/actionlint
|
||||
```
|
||||
|
||||
This environment is Linux/WSL. Android SDK and a KVM emulator were installed for
|
||||
real execution. Build output relocation was needed because the Windows mount
|
||||
rejects some Gradle POSIX metadata operations. Swift's Linux toolchain was
|
||||
installed for portable tests. No macOS, Xcode, Apple simulator or physical device
|
||||
is available; no iOS build/archive/UI result is claimed.
|
||||
On the local WSL checkout use `YUVOMI_BUILD_DIR=/home/neste/yuvomi-native-build`
|
||||
and the SDK paths from [continuation](continuation.md). Select only the authorized
|
||||
test emulator with `ANDROID_SERIAL=emulator-5554`; unrelated/unauthorized attached
|
||||
devices are not test targets.
|
||||
|
||||
## Mandatory remaining evidence
|
||||
## External gates
|
||||
|
||||
- Run Xcode build, XCTest/UI tests and unsigned archive on macOS; fix any compiler
|
||||
or runtime issues. The app has **not** yet been typechecked against Apple SDKs.
|
||||
- Validate real IdPs: cancellation, account linking, TOTP after OIDC, and embedded
|
||||
provider policy. Browser-only providers have no native-session handoff upstream.
|
||||
- Real-device camera/document picker cancellation, file MIME cases, rotation with
|
||||
an outstanding picker, network loss/reconnect, process kill/memory pressure,
|
||||
session expiry/revocation, OS backup, and offline account isolation.
|
||||
- Android 17 private-network permission grant/denial/revocation on a matching OS.
|
||||
Also run minimum-supported API 26 and a current OS/WebView device matrix.
|
||||
- VoiceOver/TalkBack, large text, contrast, keyboard/safe areas, reduced motion,
|
||||
light/dark appearance and responsive web modules on actual supported devices.
|
||||
- Successful CI runs on the configured Gitea runners, private security
|
||||
reporting contact, human security review, store ownership and production signing.
|
||||
|
||||
No Firebase/APNs registration, closed-app push, offline editing, App Store approval,
|
||||
signing, publication or physical-device validation is claimed. See `SECURITY.md`
|
||||
and `docs/security-review.md` for residual limitations.
|
||||
Resume work using [maintainer continuation](continuation.md).
|
||||
|
||||
## Gitea runner adaptation
|
||||
|
||||
Workflows now live in `.gitea/workflows/` and target the supplied `ubuntu-latest`
|
||||
pool and native `macos-arm64` M4 Pro runner. Local workflow grammar lint (Gitea URL
|
||||
syntax normalized), repository invariants, shell/Python syntax, ten mocked runner
|
||||
preflight regressions and eight evidence-verifier regressions pass. SHA-256 Git
|
||||
initialization/fetch was exercised locally; the pinned XcodeGen archive's checksum
|
||||
and native arm64 slice were verified. These are not remote runner execution or
|
||||
Apple SDK results. See [runner requirements](ci-runners.md); the local emulator
|
||||
preflight currently rejects unavailable/inaccessible KVM as designed. Original
|
||||
application build evidence above remains historical and is not a rebuild of the
|
||||
workflow-only changes.
|
||||
Apple SDK builds, real supported devices/current engines, Android API 37, native
|
||||
SSO/reset/invite protocols, permission/role cases, files/offline/notifications,
|
||||
complete module and settings parity, visual baselines, accessibility and human
|
||||
security review remain open. Missing modules are listed in
|
||||
[native parity](native-parity.md), not silently represented as working.
|
||||
Reference in new issue
Block a user