# Next Terminal Handoff - Archipelago `1.8-alpha` Last updated: 2026-06-11 00:17 America/New_York ## Resume Prompt Paste this into the next terminal/session: > Continue Archipelago `1.8-alpha` release hardening from `/home/archipelago/Projects/archy`. First read `docs/NEXT_TERMINAL_HANDOFF.md`, then `docs/RESUME.md`, `docs/CONTAINER_LIFECYCLE_HANDOFF.md`, `docs/MIGRATION_STATUS_REPORT.md`, and `docs/1.8-alpha-improvements-tracker.md`. Active validation node is `.198` at `192.168.1.198` with user `archipelago` and password `password123`. Keep `archipelago-doctor.timer` and `archipelago-reconcile.timer` inactive for deterministic validation. Do not run broad Podman store/image cleanup commands on `.198` (`podman prune`, `podman image list`, `podman system df`, broad image-exists/list/store-wide cleanup); the store/control path is known to hang under load. Preserve app data. Latest deployed backend hash on `.198` is `159e0daf13fca2df7e831122cb0e6c84223a7e5b7433f5dd0b7eec263233e228`. Fedimint Guardian public launch is fixed: `8175` serves the styled wait/proxy UI with real background/icon assets and proxies to backend Guardian on `8177`; `package.restart fedimint` now returns immediately and settled with both services active. Latest local-only tracker pass added uninstall preserve/delete-data UI, companion APK QR/download, setup instructions rendering, Fleet/Bitcoin receive-state loading improvements, Nextcloud false-update work, PhotoPrism credential fallback, and removed the Spotlight AI coming-soon block. Continue with the broader rootless Podman lifecycle/control-plane blocker, My Apps state truthfulness, progress UX, remaining in-progress tracker items, full lifecycle, clean reboot iterations, ISO cut, and ISO smoke test. ## Current Goal Cut Archipelago `1.8-alpha`, including a ready-to-test ISO image. Release status is still not green. The remaining work is mostly systemic hardening and final gates, not basic app catalog wiring. The user improvement list in `docs/1.8-alpha-improvements-tracker.md` is part of the same release and next ISO cut. Keep that tracker updated as items move from `todo` to `in-progress`, `blocked`, `done`, or explicit release deferral. ## Active Session Checkpoint - 2026-06-10 05:48 EDT New terminal resumed from this handoff. No `.198` host actions have been run in this resumed pass yet. Resume-save checkpoint, 2026-06-10 08:32 EDT: progress is saved in this handoff and `docs/1.8-alpha-improvements-tracker.md`. No `.198` host actions were run after the 05:48 checkpoint, no dev server was intentionally left running, and no long-running validation command is expected to still be active from this pass. The user explicitly wants the fixes backlog continued, not app migration work, unless they redirect. Start a resumed session by re-reading the tracker row `Make tabs info load quickly or show loading states`, then continue the slow panel audit or move to the next unresolved fixes-backlog row. Resume-save checkpoint, 2026-06-10 23:15 EDT: continued only frontend fixes backlog work and avoided Bitcoin/Tor RPC/backend paths because another agent is working there. No `.198` host actions were run, no dev server was intentionally left running, and no long-running validation command is expected to still be active from this pass. Resume-save checkpoint, 2026-06-11 00:17 EDT: continued the fixes backlog only, not app migration. Avoid Bitcoin/Tor RPC/backend work because a separate agent is working there. The latest local change fixes the header responsiveness regression the user flagged: primary My Apps/App Store/Websites navigation is restored to persistent desktop tabs at `md+` on My Apps, Discover, and Marketplace; desktop primary dropdowns were removed; mobile dropdown behavior remains; App Store category collapse is delayed by starting uncollapsed and using a smaller header gap/search reserve; My Apps desktop category dropdown was removed. Validation passed `npm run type-check`, `npm test -- --run src/views/marketplace/__tests__/MarketplaceAppCard.test.ts src/views/apps/__tests__/appsConfig.test.ts`, and scoped `git diff --check`. Browser smoke against the already-running local Vite/mock session (`http://127.0.0.1:8102` and mock backend `5959`) is still pending. Leave that existing session alone unless it has already exited. Exact first step for this pass: 1. Update the handoff docs with this fresh checkpoint. 2. Rerun local resume gates that were pending after the 05:30 checkpoint: `git diff --check` and the focused Rust image-version test for the Nextcloud false-update work. 3. If local gates are clean, continue the rootless Podman lifecycle/control-plane blocker by inspecting the backend scanner/backoff and package stop/start/ restart paths before touching `.198`. Progress in this resumed pass: - `git diff --check` passed. - `/tmp` has sufficient build headroom for focused Rust validation (`/tmp` was 14% used at the start of the pass). - Focused Rust validation for Nextcloud/image-version work is still inconclusive, not green: `env CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/tmp/archy-cargo-image-versions cargo test --manifest-path core/Cargo.toml -p archipelago container::image_versions::tests` compiled through the `archipelago` crate, then the tool PTY stayed open with no active `cargo`, `rustc`, or linker process visible in `ps`. - A bounded retry using the normal workspace target also did not finish: `timeout 300s cargo test --manifest-path core/Cargo.toml -p archipelago container::image_versions::tests` exited `124` after compiling the `archipelago` test target without reaching test output. Keep the Nextcloud false-update row `in-progress`. - Found and fixed a lifecycle asymmetry in `core/archipelago/src/api/rpc/package/runtime.rs`: `package.stop` claimed to return immediately but single-orchestrator apps still stopped synchronously before responding. The local change now lets migrated single-orchestrator apps return `{"status":"stopping"}` immediately and finish stop in the background, matching start/restart behavior. This is not deployed yet and still needs local validation. - Separate UI-only pass on port-review track: - My Apps now preserves the last known backend package list when a later scanner/backoff update reports `containers-scanned=false` with an empty package map; - the page shows `Refreshing container state. Showing the last known app list until the scan finishes.` above the app grid while cached app state is being rendered; - this touched only `neode-ui` UI files and this handoff/tracker note, so it should not conflict with the backend app migration/control-plane pass; - focused validation passed: `npm test -- --run src/views/apps/__tests__/appPackageCache.test.ts` and `npm run type-check`. - Web5 Shared Content My Content tab now keeps the current content list visible during refresh/failure and shows `Refreshing shared content...`; - Web5 Shared Content Browse Peers tab now keeps the current peer content list visible while refreshing the same peer, and shows `Refreshing peer content...` instead of replacing the tab with a full loading panel; - switching to a different peer still clears stale content and shows the full connecting state; - focused validation passed: `npm test -- --run src/views/web5/__tests__/Web5SharedContent.test.ts` and `npm run type-check`. - Local review services are running for user review: Vite `http://localhost:8102/` / `http://192.168.1.116:8102/` and mock backend `http://localhost:5959`; `curl` probes returned HTTP `200` for both the Vite root and proxied `server.get-state`. - `cargo fmt --manifest-path core/Cargo.toml --all --check` passed after the stop-path fix. - Backend compile validation for the stop-path fix passed: `env CARGO_TARGET_DIR=/tmp/archy-cargo-runtime-check cargo check --manifest-path core/Cargo.toml -p archipelago --bin archipelago`. The first check session also eventually returned success after the bounded rerun waited on its build-directory lock. - `git diff --check` passed again after the stop-path edit and doc updates. - Follow-up inspection confirmed the lower-level Quadlet/orchestrator stop path is already bounded: `quadlet::stop_service` uses timed `systemctl --user stop` with app-scoped kill/reset recovery, and the runtime fallback treats missing containers as success. No additional lower-level stop change was made in this pass. - Latest backlog-fix pass stayed on the fixes tracker, not new app migration: - backend `package.credentials` now returns manifest-backed PhotoPrism credentials (`admin` / `archipelago`) directly, matching the existing UI fallback; - My Apps and mobile icon-grid credential pre-launch modals are centered vertically on mobile instead of behaving like bottom sheets; - validation passed: `npm test -- --run src/views/apps/__tests__/appCredentials.test.ts src/views/apps/__tests__/AppIconGrid.test.ts`, `npm run type-check`, `env CARGO_TARGET_DIR=/tmp/archy-cargo-runtime-check timeout 300s cargo check --manifest-path core/Cargo.toml -p archipelago --bin archipelago`, `cargo fmt --manifest-path core/Cargo.toml --all --check`, and `git diff --check`. - Focused Nextcloud/image-version Rust test is still not green: `env CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=/tmp/archy-cargo-image-versions-2 timeout 600s cargo test --manifest-path core/Cargo.toml -p archipelago container::image_versions::tests -- --nocapture` again exited `124` after compiling into the `archipelago` crate without reaching test output. Keep that tracker row `in-progress`. - Continued the tab loading-state backlog: - Web5 Connected Nodes Messages and Requests tabs keep populated lists visible during refresh or refresh failure; - Web5 Identities keeps the current identity list visible during refresh or refresh failure and shows `Refreshing identities...`; - Web5 DWN message browsing keeps stored messages visible during refresh or refresh failure and shows `Refreshing messages...`; - validation passed: `npm test -- --run src/views/web5/__tests__/Web5ConnectedNodes.test.ts src/views/web5/__tests__/Web5Identities.test.ts src/views/web5/__tests__/Web5DWN.test.ts` and `npm run type-check`. - Continued the same tab/loading-state backlog on Server networking: - Server Network overview keeps current values visible during refresh/failure and shows `Refreshing network...`; - Server Network Interfaces keeps current detected interfaces visible during refresh/failure and shows `Refreshing interfaces...`; - Server Tor Services keeps existing hidden-service rows visible during refresh/failure and shows `Refreshing Tor services...`; - validation passed: `npm test -- --run src/views/__tests__/ServerNetworkRefresh.test.ts` and `npm run type-check`. - Continued the same loading-state backlog on Credentials: - the Credentials list keeps existing credential rows visible during refresh/failure and shows `Refreshing credentials...`; - validation passed: `npm test -- --run src/views/__tests__/CredentialsRefresh.test.ts src/views/__tests__/ServerNetworkRefresh.test.ts` and `npm run type-check`. - Continued the same loading-state backlog on Lightning Channels: - the channels list keeps existing channels visible during refresh/failure and shows `Refreshing channels...`; - validation passed: `npm test -- --run src/views/apps/__tests__/LightningChannels.test.ts src/views/__tests__/CredentialsRefresh.test.ts src/views/__tests__/ServerNetworkRefresh.test.ts` and `npm run type-check`. - Continued the same loading-state backlog on Peer Files: - the peer catalog keeps existing file cards visible during Tor refresh/failure and shows `Refreshing peer files...`; - validation passed: `npm test -- --run src/views/__tests__/PeerFilesRefresh.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on Cloud peer cards: - Cloud keeps existing peer cards visible during federation peer-list refresh/failure and shows `Refreshing peer nodes...`; - validation passed: `npm test -- --run src/views/__tests__/CloudPeersRefresh.test.ts src/views/__tests__/PeerFilesRefresh.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on the Web5 Verifiable Credentials summary: - the summary keeps existing credential rows visible during refresh/failure and shows `Refreshing credentials...`; - validation passed: `npm test -- --run src/views/web5/__tests__/Web5CredentialsSummary.test.ts src/views/__tests__/CloudPeersRefresh.test.ts src/views/__tests__/PeerFilesRefresh.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on Web5 Nostr Relays: - relay stats stay visible during refresh/failure and show `Refreshing relays...`; - validation passed: `npm test -- --run src/views/web5/__tests__/Web5NostrRelays.test.ts src/views/web5/__tests__/Web5CredentialsSummary.test.ts src/views/__tests__/CloudPeersRefresh.test.ts src/views/__tests__/PeerFilesRefresh.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on Web5 Domains: - registered-name counts stay visible during refresh/failure and show `Refreshing domains...`; - validation passed: `npm test -- --run src/views/web5/__tests__/Web5Domains.test.ts src/views/web5/__tests__/Web5NostrRelays.test.ts src/views/web5/__tests__/Web5CredentialsSummary.test.ts src/views/__tests__/CloudPeersRefresh.test.ts src/views/__tests__/PeerFilesRefresh.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on Settings Backups: - existing backup rows stay visible during refresh/failure and show `Refreshing backups...`; - validation passed: `npm test -- --run src/views/settings/__tests__/BackupSection.test.ts src/views/web5/__tests__/Web5Domains.test.ts src/views/web5/__tests__/Web5NostrRelays.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on Settings Transport Preferences: - existing preference controls stay visible during refresh/failure and show `Refreshing transport preferences...`; - validation passed: `npm test -- --run src/views/settings/__tests__/TransportPrefsCard.test.ts src/views/settings/__tests__/BackupSection.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on Settings VPN status: - current VPN connection details stay visible during refresh/failure and show `Refreshing VPN status...`; - validation passed: `npm test -- --run src/views/settings/__tests__/VpnStatusSection.test.ts src/views/settings/__tests__/TransportPrefsCard.test.ts src/views/settings/__tests__/BackupSection.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the same loading-state backlog on Web5 Federation: - summary node counts and node DID stay visible during refresh/failure and show `Refreshing federation...`; - validation passed: `npm test -- --run src/views/web5/__tests__/Web5Federation.test.ts`, `npm run type-check`, and `git diff --check`. - Continued the Mesh map denied-location backlog: - added component coverage that browser geolocation denial remains optional and tells the user peer positions can still appear; - validation passed: `npm test -- --run src/components/__tests__/MeshMap.test.ts`, `npm run type-check`, and `git diff --check`. - row remains `in-progress` until browser smoke validates denied location with a real peer coordinate message. - Continued the companion/tab-app backlog: - mobile app-session keeps apps that require a new tab inside the mobile session fallback instead of auto-opening an external tab and closing; - validation passed: `npm test -- --run src/views/__tests__/AppSessionMobileNewTab.test.ts src/views/appSession/__tests__/appSessionConfig.test.ts src/stores/__tests__/appLauncher.test.ts`, `npm run type-check`, and `git diff --check`. - row remains `in-progress` until broader companion smoke testing is done. - Continued the Nostr Discoverable Nodes UI backlog: - Discover modal keeps existing discovered rows visible during relay refresh/failure and shows `Searching relays...`; - validation passed: `npm test -- --run src/views/federation/__tests__/DiscoverModal.test.ts`, `npm run type-check`, and `git diff --check`. - row remains `in-progress` until live relay/trust validation is done. - Continued the App Store screenshots backlog: - Marketplace App Details and installed App Details no longer show fake screenshot placeholder tiles when no screenshot metadata exists; - both views now render real screenshot URLs when metadata is provided as strings or `{ src, alt }` objects; - validation passed: `npm test -- --run src/views/appDetails/__tests__/AppContentSection.test.ts src/composables/__tests__/useMarketplaceApp.test.ts`, `npm run type-check`, and `git diff --check`; - row remains `in-progress` until real screenshot assets/metadata are added. - Continued the Home/App Store recommendations backlog: - Home now shows an App Store recommendations card with up to three uninstalled core/recommended marketplace apps; - the selector respects installed aliases, so recommended apps drop out once installed and then rely on normal My Apps/Home behavior; - card clicks reuse the existing Marketplace App Details handoff; - card animation ordering was tightened so Home cards have a stable stagger sequence as the recommendations card appears/disappears; - validation passed: `npm test -- --run src/views/home/__tests__/homeRecommendations.test.ts`, `npm run type-check`, `git diff --check`, and `ARCHY_BASE_URL=http://127.0.0.1:8103 npx playwright test e2e/visual-regression.spec.ts -g 'home / dashboard' --project=chromium`; - temporary Vite on `8103` was stopped after the smoke. An older local dev/mock session on `8102`/`5959` was already present and was left alone. - tracker row is `done`. - Home layout follow-up: - Cloud was moved back into the second card slot; - Recommended Apps moved into Cloud's previous position; - Quick Start now lives inside the dashboard grid next to Wallet, with stacked goal buttons, instead of rendering as a separate odd-width row; - validation passed: `npm test -- --run src/views/home/__tests__/homeRecommendations.test.ts`, `npm run type-check`, `git diff --check`, and `ARCHY_BASE_URL=http://127.0.0.1:8102 npx playwright test e2e/visual-regression.spec.ts -g 'home / dashboard' --project=chromium`. - Continued the Easy Mode experience backlog: - goal configure steps now route to their owning app/screen instead of silently completing without navigation; - verify steps now show `Check & Continue`, so goals that start with a verify step are no longer stuck without an active action; - configure/info/verify actions start goal progress before completing the current step; - validation passed: `npm test -- --run src/views/goals/__tests__/goalStepActions.test.ts src/stores/__tests__/goals.test.ts`, `npm run type-check`, and `git diff --check`; - tracker row is `in-progress` because broader Easy Mode product scope still needs review. - Continued the setup screens/function/flow backlog: - onboarding setup choice now shows only usable paths, Fresh Start and Restore from Seed; - removed the disabled `Connect Existing (Coming Soon)` option; - validation passed: `npm test -- --run src/views/__tests__/OnboardingOptions.test.ts src/composables/__tests__/useOnboarding.test.ts`, `npm run type-check`, and `git diff --check`; - tracker row is `in-progress` because broader onboarding/setup audit still needs review. ## Latest Local Checkpoint - 2026-06-10 05:30 EDT User paused work to switch machines. No dev server or validation command should be intentionally left running from this checkpoint. Latest local-only release-tracker work since the older `.198` handoff: - Uninstall/data reset: - My Apps and App Details uninstall dialogs now include `Delete app data and reset it`; - unchecked preserves app data and sends `preserve_data=true`; - checked sends `preserve_data=false`; - covered by `AppsUninstallModal.test.ts`, `rpc-client.test.ts`, type-check, and `git diff --check`; - tracker row is `done`. - Companion APK: - companion intro modal uses `VITE_COMPANION_APK_URL` or `/packages/archipelago-companion.apk.zip`; - desktop shows a centered QR image generated with the same `qrcode` library used by wallet flows; - mobile shows a direct download button; - visible close button restored; - APK exists at `neode-ui/public/packages/archipelago-companion.apk.zip`; - tracker row is `done`. - Setup instructions: - App Details sidebar renders `static-files.instructions` when non-empty; - covered by `AppSidebar.test.ts`, type-check, and `git diff --check`; - tracker row is `done`. - Fleet / tab loading: - Fleet auto-refresh header/sort controls were tightened; - node history no longer blanks during refresh and now shows `Refreshing history...`; - covered by `useFleetData.test.ts`, type-check, and `git diff --check`; - tracker row remains `in-progress` pending broader slow-tab audit. - Bitcoin receive readiness: - receive modals show a live `Checking Lightning wallet readiness...` message while on-chain address generation is in flight; - shared helper now distinguishes LND REST/newaddress transport failures; - covered by `bitcoinReceive.test.ts`, type-check, and `git diff --check`; - tracker row remains `in-progress` pending live wallet-state smoke test. - Nextcloud false update: - Nextcloud manifest/catalog/static UI metadata moved from `28` to pinned `29`; - update comparison now ignores registry-host-only image changes while reporting same-repo tag drift; - `python3 scripts/check-app-catalog-drift.py --release --strict` passed; - `cargo test -p archipelago container::image_versions::tests` from `core/` failed first with a Rust linker/incremental artifact issue after `/tmp` was full, then the non-incremental retry was killed because it ran too long; - old `/tmp/archy-cargo-*` build-cache directories were removed and `/tmp` recovered to about 14% used; - tracker row is `in-progress`; rerun the focused Rust test before marking done. - Dead/coming-soon UI: - removed the non-interactive Spotlight AI Assistant coming-soon block; - verified no active UI `Coming soon` strings remain outside historical release-note text; - type-check passed and `git diff --check` passed; - tracker row is `done`. - No-registration credentials: - added PhotoPrism fallback credentials from its manifest (`admin` / `archipelago`); - did not add Grafana because its `GRAFANA_ADMIN_PASSWORD` is not resolved to a known local secret/default in the repo; - `npm test -- --run src/views/apps/__tests__/appCredentials.test.ts` passed; - `npm run type-check` passed; - tracker row still `in-progress` because other no-registration apps still need inventory. Most recent validations before pause: - `npm run type-check` passed after the PhotoPrism credential fallback. - `npm test -- --run src/views/apps/__tests__/appCredentials.test.ts` passed. - `git diff --check` passed after the Spotlight cleanup and before the PhotoPrism fallback; rerun it after resuming. - `python3 scripts/check-app-catalog-drift.py --release --strict` passed during the Nextcloud pass. - Backend Rust focused validation for image versions is still not clean because of the local linker/incremental artifact failure and the killed retry; rerun from `core/` when convenient. ## Latest Known `.198` State - Host: `192.168.1.198`. - Backend deployed: `/usr/local/bin/archipelago` sha256 `159e0daf13fca2df7e831122cb0e6c84223a7e5b7433f5dd0b7eec263233e228`. - `archipelago.service`: active after deploy. - `archipelago-doctor.timer`: inactive. - `archipelago-reconcile.timer`: inactive. - No reboot validation should be started yet. ## What Was Just Done - Investigated current Fedimint Guardian UI report: - live `.198` RPC reports `fedimint` as `starting` and `container-health {"fedimint":"starting"}`; - direct `http://192.168.1.198:8175/` returns HTTP `000` because the manifest wrapper has not exec'd `fedimintd` yet; - `bitcoin-knots` is `running` and `http://192.168.1.198:8334/` returns HTTP `200`; - `bitcoin.status` RPC returned an operation-failed error during the check, consistent with the current Bitcoin-dependent-app wait-state problem. - Added frontend Fedimint-specific wait-state copy: - My Apps/App card now says `Waiting for Bitcoin to finish initial sync before Guardian starts.` when Fedimint is starting or running with `health=starting`; - App session fallback title now says `Waiting for Bitcoin sync` instead of generic `App not reachable` for that state. - Validated frontend changes: - `npm test -- --run src/views/apps/__tests__/appsConfig.test.ts` passed (`7` tests); - `npm run type-check` passed; - `npm run build` passed. - Deployed rebuilt static frontend to `.198` only: - preserved `aiui/` and `claude-login.html`; - backed up previous web root at `/opt/archipelago/rollback/web-ui-fedimint-ui-20260610-042927.tar`; - reloaded nginx; - confirmed deployed assets contain the new Fedimint copy. - Fixed Fedimint Guardian launch on `.198` while Bitcoin is still syncing: - added `docker/fedimint-ui`, an nginx wait/proxy companion; - changed Fedimint backend manifest so real Guardian UI maps to host `8177` instead of the public launch port; - public launch port `8175` is now owned by `archy-fedimint-ui`, which serves `Waiting for Bitcoin sync` until `fedimintd` binds behind it; - fixed the Fedimint wait command to avoid `printf '%s'` in Quadlet `Exec=` because systemd expands `%s` to the user shell (`/bin/bash`); - live `.198` `fedimint.service` unit has `TimeoutStartSec=infinity` so systemd does not kill the intentional Bitcoin-sync wait loop; - rebuilt and deployed frontend static files so Fedimint remains launchable while `health=starting`; - confirmed `http://192.168.1.198:8175/` returns HTTP `200` with `Waiting for Bitcoin sync`. - Restyled the Fedimint wait/proxy page: - `docker/fedimint-ui/index.html` now uses Archipelago-style `glass-card`, app icon block, Montserrat-like heading stack, orange focus/glow accents, and yellow starting badge styling; - rebuilt `localhost/fedimint-ui:latest` on `.198`; - restarting `archy-fedimint-ui.service` hit the known rootless Podman cleanup slowness and left the unit temporarily `deactivating`; - recovered with app-scoped `systemctl --user kill --kill-whom=all -s SIGKILL archy-fedimint-ui.service`, `reset-failed`, and `start`; - final LAN validation: `http://192.168.1.198:8175/` returns HTTP `200`, size `6419`, and contains `glass-card`, `app-icon`, `Archipelago App`, and `Waiting for Bitcoin sync`. - Updated the Fedimint wait/proxy page again per design feedback: - uses the Bitcoin custom UI's `/assets/img/bg-network.jpg` full-screen background + dark overlay pattern; - uses the real Fedimint icon inside the Bitcoin custom UI `logo-gradient-border` treatment instead of text initials; - copied those assets into `docker/fedimint-ui/assets/`; - rebuilt `localhost/fedimint-ui:latest` on `.198`; - fixed nginx routing so `/assets/...` is served statically instead of being proxied to the not-yet-running Guardian backend; - corrected the companion page to reference `fedimint.jpg` because the catalog icon bytes are JPEG despite the old `.png` extension; - final LAN validation: `http://192.168.1.198:8175/` returns HTTP `200`, size `11328`; `/assets/img/app-icons/fedimint.jpg` returns `200 image/jpeg`; `/assets/img/bg-network.jpg` returns `200 image/jpeg`; - Playwright render validation confirmed title `Fedimint Guardian`, status `Waiting for Bitcoin sync`, background URL `/assets/img/bg-network.jpg`, and icon natural width `860`. - Hardened Fedimint/backend lifecycle enough for this path: - generated Quadlet services now include `TimeoutStartSec=0` so systemd does not kill dependency-gated container entrypoints while they wait for Bitcoin IBD; - `package.restart` now returns `{"status":"restarting"}` immediately instead of blocking the RPC call for minutes in the single-orchestrator path; - `quadlet::restart_service` now uses bounded stop/start, app-scoped kill/reset recovery, and settle waits instead of opaque `systemctl restart`; - deployed backend hash `159e0daf13fca2df7e831122cb0e6c84223a7e5b7433f5dd0b7eec263233e228` to `.198`; - backup made at `/opt/archipelago/rollback/archipelago-before-quadlet-timeout0-20260610-082535`; - `package.restart fedimint` returned `{"status":"restarting"}` in `0s`; - restart observation: `8175` stayed HTTP `200` throughout; generated `fedimint.container` gained `TimeoutStartSec=0`; `fedimint.service` and `archy-fedimint-ui.service` settled `active`; ports `8175` and `8177` listened. - Final Fedimint live validation after restart: - `container-health` returned `{"fedimint":"healthy"}`; - `container-list` returned `fedimint` `state:"running"` and `lan_address:"http://localhost:8175"`; - services: `fedimint.service` active, `archy-fedimint-ui.service` active; - unit contains `TimeoutStartSec=0` at line `42`; - public wait/proxy UI and both image assets returned `200`. - Fedimint live rollback references: - previous frontend backup: `/opt/archipelago/rollback/web-ui-fedimint-guardian-launch-20260610-045949.tar`; - previous Fedimint Quadlet backup: `/home/archipelago/.config/containers/systemd/fedimint.container.guardian-fix-rewrite-20260610-050607.bak`. - Earlier backend hash `7f58da80063f58574675256913ac9cddf131e65d8935015748a70adffc228f83` was superseded by `159e0daf13fca2df7e831122cb0e6c84223a7e5b7433f5dd0b7eec263233e228`. - Added explicit release gates: - app packaging docs must match current manifest/runtime contract before `1.8-alpha`; - refactor/remove-dead-code is mandatory before `1.8-alpha`, after correctness validation and before final ISO/release gates. - Validated IndeeHub: - `container-list` reported `indeedhub` running; - `container-health` returned `{"indeedhub":"healthy"}`; - `http://192.168.1.198:7778/` returned HTTP `200`; - `http://192.168.1.198:7778/nostr-provider.js` returned HTTP `200` and contains the Archipelago NIP-07/NIP-98 provider shim. - Validated Immich launch: - `http://192.168.1.198:2283/` returned HTTP `200`; - one `container-health` check returned `{"immich":"unknown"}`, so health truthfulness still needs follow-up. - Fixed Tailscale launch UI: - patched `app-catalog/catalog.json`, `neode-ui/public/catalog.json`, and `scripts/first-boot-containers.sh`; - command now waits for `/var/run/tailscale/tailscaled.sock` before starting `tailscale web`; - copied updated catalog to `/opt/archipelago/web-ui/catalog.json` on `.198`; - patched the live generated Tailscale `.container` unit and restarted only `tailscale.service`; - confirmed `container-list` reports Tailscale running; - confirmed `container-health` returns `{"tailscale":"healthy"}`; - confirmed `http://192.168.1.198:8240/` returns HTTP `200` with Tailscale UI content. ## Important Caveat Tailscale launch is fixed, but Tailscale lifecycle is not fully passing: - `package.restart tailscale` failed through RPC with `podman ps timed out while listing containers`. - Manual app-scoped restart showed old container stop needed SIGKILL and Podman cleanup took roughly 2 minutes. - Logs still showed `podman ps timed out`, `podman stats timed out`, scan backoff, and slow cleanup. This confirms the active blocker is the rootless Podman control-plane/lifecycle path, not just individual app launch URLs. ## Active Blockers - Rootless Podman/control-plane responsiveness: - `podman ps` and cleanup paths time out; - backend scan/backoff causes stale or slow UI state; - app stop/start/restart can look frozen or fail through RPC. - My Apps state truthfulness: - do not show false empty/no-apps while scanner/Podman is in backoff; - preserve last-known apps and show explicit stale/checking state. - Progress UX: - install/uninstall/start/stop/restart must show meaningful phase progress and not appear frozen. - Immich health truthfulness: - HTTP launch works, but health may still report `unknown`. - Portainer: - HTTP `9000` returned `200`; - user still needs to retry environment wizard and confirm `/var/run/docker.sock` works. - Fedimint: - public Guardian launch URL now loads on `8175` even while Bitcoin is in IBD; - `archy-fedimint-ui` owns `8175` and proxies to the real Guardian backend on `8177` when `fedimintd` eventually starts; - durable manifest/companion/frontend/backend changes are now deployed on `.198`; - `package.restart fedimint` fast-returned and settled active with `TimeoutStartSec=0`, but keep Fedimint in the broader lifecycle matrix because rootless Podman cleanup slowness remains a systemic blocker. - Reboot validation: - require at least 3 clean consecutive post-fix reboots with broad lifecycle green after each; - prefer 5 clean reboots; - do not start until lifecycle/control-plane is stable. - App packaging docs: - aligned `docs/APP-PACKAGING-MIGRATION-PLAN.md` and `docs/app-developer-guide.md` with the current manifest/runtime contract. - Refactor/remove-dead-code: - required before `1.8-alpha`; - remove stale per-app hacks, duplicate lifecycle paths, stale fallback metadata, misleading compatibility shims; - rerun release gates afterward. ## Local Validation Already Run - `bash -n tests/lifecycle/remote-lifecycle.sh` passed. - `bash -n scripts/first-boot-containers.sh tests/lifecycle/remote-lifecycle.sh` passed. - `cargo fmt --manifest-path core/Cargo.toml --all` was run. - `cargo test --manifest-path core/Cargo.toml -p archipelago-container` passed (`45` tests). - `cargo check --manifest-path core/Cargo.toml -p archipelago -p archipelago-container` passed. - `python3 scripts/check-app-catalog-drift.py --release --strict` passed. - `cmp -s app-catalog/catalog.json neode-ui/public/catalog.json` passed. - `git diff --check` passed. - `npm test -- --run src/views/apps/__tests__/appsConfig.test.ts` passed. - `npm run type-check` passed. - `npm run build` passed. - `python3 scripts/check-app-catalog-drift.py --release --strict` passed after Fedimint manifest changes. - `git diff --check` passed for Fedimint manifest, companion, frontend, and new `docker/fedimint-ui` files. - `cargo fmt --manifest-path core/Cargo.toml --all` passed. - `CARGO_TARGET_DIR=/tmp/archy-cargo-check-quadlet cargo check --manifest-path core/Cargo.toml -p archipelago -p archipelago-container` passed after Quadlet/restart changes. - `CARGO_TARGET_DIR=/tmp/archy-cargo-final-quadlet cargo build --manifest-path core/Cargo.toml -p archipelago --bin archipelago --release` produced the deployed backend binary (tool PTY heartbeat wrapper became stale after link; artifact hash was validated separately before deploy). - Live Fedimint restart validation passed on `.198`: - `package.restart fedimint` returned `{"status":"restarting"}` immediately; - `8175` remained HTTP `200`; - `fedimint.service` and `archy-fedimint-ui.service` settled `active`; - `container-health fedimint` returned `healthy`. - `cargo test --manifest-path core/Cargo.toml -p archipelago companion::tests` compiled then the tool PTY stuck with no active `cargo`/`rustc` process visible; treat as inconclusive, not failed. - Filtered `cargo test --manifest-path core/Cargo.toml -p archipelago --bin archipelago indeedhub` appeared wedged in the tool PTY after compilation started; no local cargo/rustc worker remained visible. Treat as inconclusive, not failed. ## Immediate Next Step Do not reboot yet. Start with the rootless Podman lifecycle/control-plane blocker: 1. Inspect the backend stop/start/restart path around `package.restart`, scanner backoff, and `podman ps` dependency. 2. Make stop/restart tolerate slow cleanup without wedging RPC/UI state. 3. Keep last-known app state during scanner backoff. 4. Revalidate focused apps on `.198`: `tailscale`, `indeedhub`, `immich`, `portainer`, `vaultwarden`, `botfights`; keep `fedimint` in the matrix but its focused Guardian launch/restart path is currently green. 5. Only after focused lifecycle is clean, run broad non-destructive lifecycle. 6. Only after that, begin 3/5 reboot validation. ## Files Touched In Last Mini-Pass - `docs/NEXT_TERMINAL_HANDOFF.md` - this file. - `neode-ui/src/views/apps/appsConfig.ts` - Fedimint launch-blocked reason helper. - `neode-ui/src/views/apps/AppCard.vue` - show Fedimint Bitcoin-sync wait copy on app cards. - `neode-ui/src/views/AppSession.vue` - pass app-specific blocked reason into app session. - `neode-ui/src/views/appSession/AppSessionFrame.vue` - show app-specific blocked title/reason instead of generic unreachable fallback. - `neode-ui/src/views/apps/__tests__/appsConfig.test.ts` - regression coverage for Fedimint wait-state copy. - `apps/fedimint/manifest.yml` - backend real Guardian UI now maps host `8177` and wait command avoids systemd `%` expansion. - `core/archipelago/src/container/companion.rs` - added `archy-fedimint-ui` companion mapping. - `core/archipelago/src/container/quadlet.rs` - generated unit `TimeoutStartSec=0` plus bounded stop/restart recovery helpers. - `core/archipelago/src/api/rpc/package/runtime.rs` - restart RPC returns immediately and runs restart async. - `docker/fedimint-ui/` - new nginx wait/proxy companion image for Fedimint Guardian launch. - `docs/RESUME.md` - checkpoint and gates. - `docs/MIGRATION_STATUS_REPORT.md` - packaging/refactor release gates. - `docs/CONTAINER_LIFECYCLE_HANDOFF.md` - packaging/refactor release gates. - `docs/APP-PACKAGING-MIGRATION-PLAN.md` - updated manifest/runtime contract documentation. - `docs/app-developer-guide.md` - updated manifest/runtime contract documentation. - `docs/MIGRATION_STATUS_REPORT.md` - noted that the docs gate is being closed in this pass. - `app-catalog/catalog.json` - Tailscale socket-wait startup command. - `neode-ui/public/catalog.json` - same Tailscale catalog update. - `scripts/first-boot-containers.sh` - same Tailscale first-boot startup update. - `neode-ui/src/views/apps/appPackageCache.ts` - UI-only last-known package cache for scanner backoff. - `neode-ui/src/views/apps/__tests__/appPackageCache.test.ts` - cache behavior coverage. - `neode-ui/src/views/Apps.vue` - uses cached packages during scanner backoff and shows a refresh status banner. - `docs/1.8-alpha-improvements-tracker.md` - noted My Apps backoff cache improvement. - `neode-ui/src/views/web5/Web5SharedContent.vue` - preserves shared/peer content during refresh and shows compact refresh states. - `neode-ui/src/views/web5/__tests__/Web5SharedContent.test.ts` - shared and peer content refresh regression coverage. The worktree has many other pre-existing release-hardening changes. Do not revert unrelated dirty files.