fix: migrate pre-wizard gateway profiles

This commit is contained in:
Hermes Agent
2026-07-24 20:30:13 +00:00
parent 06b211a7f7
commit b2642df2ca
4 changed files with 27 additions and 3 deletions
+2
View File
@@ -58,6 +58,7 @@ All notable Hermes Mobile source changes are recorded here. Entries are added du
- Ignored `.gradle-user/` and `.dev/` alongside existing generated build artifacts.
### Fixed
- Fixed the setup gate so valid pre-wizard bearer profiles already stored under the current connection keys receive the one-time completion migration; untested no-auth first-run profiles remain gated.
- Fixed first-run setup so a profile saved by a failed/offline compatibility test cannot bypass mandatory setup after process restart; only completed or migrated valid profiles skip the wizard.
- Fixed durable stream completion so a stale request ID cannot publish a terminal state or clear a newer reservation.
- Fixed stream failure handling so HTTP, I/O, and malformed-SSE failures are reported and reduced only against the original lease, while upstream `error` events remain session failures rather than route failures.
@@ -66,6 +67,7 @@ All notable Hermes Mobile source changes are recorded here. Entries are added du
- Fixed companion/mobile lint issues from missing Node globals and an unused React settings value.
### Verification
- `./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest --tests 'cloud.molberg.hermesmobile.onboarding.SetupWizardReducerTest' :app:assembleDebug` — passed (43 tasks, 9 executed), including the new current-key migration regression.
- Task 5 re-verification on 2026-07-24: `/root/.openclaw/workspace/scripts/hermes-mobile-preflight.sh` passed; `./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest :app:assembleDebug` passed (43 tasks up-to-date); direct JUnit execution passed all 105 source-current compiled tests; the source-current debug APK reports package `cloud.molberg.hermesmobile`, version `0.1.0-beta.1` (`10001`), and SHA-256 `45f9a4bff72db21fd6e57d30db0eef8fefb429657a40357695e330cdc4906401`; `git diff --check` passed. No device/install, release, or real credential verification is claimed.
- `./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest --tests 'cloud.molberg.hermesmobile.onboarding.SetupWizardReducerTest'` — passed (28 tests), after the new regression first failed as expected.
- `./gradlew --offline --no-daemon -Dorg.gradle.jvmargs= -Dorg.gradle.daemon=false -Pkotlin.compiler.execution.strategy=in-process :app:testDebugUnitTest :app:assembleDebug` — passed (43 tasks, 4 executed).
+2
View File
@@ -58,6 +58,8 @@ _Move finished items here with date, commit, and verification. Keep this section
- Added direct password login through `/auth/password-login`, allowlisted session-cookie extraction, encrypted cookie/password storage, credential redaction, replacement/retention rules, and cookie-authenticated gateway probes without persisting raw credentials in UI state or connection forms.
- Added Settings entry for editing the same profile, skip behavior for existing valid configurations, one-time legacy/current-profile setup-version migration, and accessible adaptive Compose semantics plus phone/tablet/light/dark previews.
- Fixed a restart bypass: a profile saved by a failed first-run connection test remains in mandatory setup until setup completion is durably recorded; valid migrated and completed profiles still skip setup.
- Repaired current-key existing-user migration: a valid pre-wizard bearer profile stored under the then-current connection keys now receives the one-time completion migration, while untested no-auth profiles remain mandatory.
- Verification for the migration repair: source-current offline focused `SetupWizardReducerTest` plus `:app:assembleDebug` passed (43 tasks, 9 executed); `git diff --check` passed.
- Verification on 2026-07-24: source-current offline `:app:testDebugUnitTest :app:assembleDebug` passed (43 tasks, 4 executed; all unit tests passed), including the focused restart-regression test; `git diff --check` passed. No device, release, or real gateway credential test is claimed.
- Task 5 re-verification on 2026-07-24: `/root/.openclaw/workspace/scripts/hermes-mobile-preflight.sh` passed; the documented offline Gradle `:app:testDebugUnitTest :app:assembleDebug` command passed (43 tasks up-to-date); direct JUnit execution of the source-current compiled classes passed all 105 tests; and `git diff --check` passed. The source-current debug APK reports package `cloud.molberg.hermesmobile`, version `0.1.0-beta.1` (`10001`), and SHA-256 `45f9a4bff72db21fd6e57d30db0eef8fefb429657a40357695e330cdc4906401`. No device, release, APK installation, or real credential verification is claimed.
- [x] **R2a — Establish beta source packaging and install documentation** — 2026-07-24, commit `3b883bd` (`build: establish Android beta packaging`).
@@ -257,10 +257,10 @@ object SetupWizardReducer {
hasLegacyConfiguration: Boolean
): SetupGateResolution {
val entry = entry(config)
val existing = entry is SetupEntry.ExistingConfiguration
val existing = entry as? SetupEntry.ExistingConfiguration
val migrateExistingUser = setupVersion < CURRENT_SETUP_VERSION &&
hasLegacyConfiguration &&
existing
existing != null &&
(hasLegacyConfiguration || existing.configuration.isPreWizardCurrentConfiguration())
return SetupGateResolution(
entry = if (setupVersion >= CURRENT_SETUP_VERSION || migrateExistingUser) {
entry
@@ -513,6 +513,9 @@ private fun StoredGatewayConfiguration.isValid(): Boolean {
}
}
private fun StoredGatewayConfiguration.isPreWizardCurrentConfiguration(): Boolean =
authChoice == SetupAuthChoice.Bearer && hasBearerCredential
private fun ConnectionConfig.toStoredGatewayConfiguration(): StoredGatewayConfiguration =
StoredGatewayConfiguration(
localUrl = localUrl,
@@ -198,6 +198,23 @@ class SetupWizardReducerTest {
assertTrue(editState.canExit)
}
@Test
fun validPreWizardCurrentKeyConfigSkipsSetupAndRequestsVersionMigration() {
val resolution = SetupWizardReducer.resolveEntry(
config = ConnectionConfig(
localUrl = LOCAL,
remoteUrl = REMOTE,
authMode = ConnectionAuthMode.BearerToken,
hasBearerToken = true
),
setupVersion = 0,
hasLegacyConfiguration = false
)
assertTrue(resolution.entry is SetupEntry.ExistingConfiguration)
assertTrue(resolution.migrateExistingUser)
}
@Test
fun migrationNeverTurnsInvalidLegacyConfigIntoCompletedSetup() {
val resolution = SetupWizardReducer.resolveEntry(