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

573 lines
38 KiB
Markdown

# 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.