archy/docs/NEXT_TERMINAL_HANDOFF.md
2026-06-11 00:24:54 -04:00

38 KiB

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.