- AccountInfoSection.vue: append 5th bullet to v1.7.43-alpha entry explaining that update-available badges and version comparisons work again now that the pinned-image catalog is found at the correct deployed path. - docs/MARKETPLACE-QA.md: new tracker for the upcoming app-by-app install walk on .228. Documents the per-app fix workflow, the four layers we might need to fix at (app recipe, registry image, backend orchestrator, frontend), status-key table for tracking each catalog entry, and the release-notes policy for the walk. - docs/RESUME.md: refresh with a9908597 commit, updated binary md5 on .228, and split Immediate Next Step into Phase 1 (browser verification) and Phase 2 (marketplace walk) with a pointer to the new tracker.
11 KiB
RESUME — Install UX polish round (v1.7.43-alpha)
Last updated: 2026-04-23
Read this first if you're a fresh OpenCode session resuming the install/uninstall/update UX work.
Where we are right now
v1.7.43-alpha shipped and deployed to .228. Latest addition: image-versions.sh path bug fixed (silent update-check failure on all production nodes). User is about to walk the marketplace app-by-app on .228 to shake out any remaining broken apps. Tracker for that walk: docs/MARKETPLACE-QA.md.
Commits on .116:main (newest first, unpushed per user mirror protocol):
a9908597fix(image-versions): locate image-versions.sh at its actual deployed path013e8df0docs(resume): add RESUME.md for context-restart recoveryf9fef8d2docs(status): record rounds 3-5 + config migration + changelog as shipped008da477docs(changelog): add v1.7.43-alpha entry covering async lifecycle + .23 retirement0ee16820fix(config): auto-purge decommissioned .23 VPS from saved registry/mirror configs22052325chore: retire .23 VPS mirror, promote .168 OVH to primaryf86d86c3fix(install): kick scanner post-install so Launch button appears immediately8cc84ebcfeat(install): phase-based progress bar replaces unparseable pull bytes2d5b859efeat(rpc): async-spawn install/uninstall/update lifecycle (Round 2)0733ac40fix(ui): shorten install/uninstall/update timeouts for async RPCs (Round 2)e471ef75fix(rpc): empty icon in transient install entry (Round 2)
Deployed artifacts on .228:
- Backend:
/usr/local/bin/archipelagomd59b8ead06aaf210b85cd78fce270384e3(includes image-versions path fix) - Frontend:
/opt/archipelago/web-ui/(v1.7.43-alpha changelog with 5 bullets, .168-only registry) - Rollback backups:
/usr/local/bin/archipelago.bak-pre-async-install+/opt/archipelago/web-ui.bak-pre-async-install/
Rollback command (if catastrophic):
ssh archy228 'sudo cp -a /usr/local/bin/archipelago.bak-pre-async-install /usr/local/bin/archipelago && sudo rsync -a --delete /opt/archipelago/web-ui.bak-pre-async-install/ /opt/archipelago/web-ui/ && sudo systemctl restart archipelago && sudo systemctl reload nginx'
Immediate next step
Phase 1 — browser verification of v1.7.43-alpha on https://192.168.1.228/
- Settings → About: top changelog entry reads "v1.7.43-alpha · Apr 23, 2026" with 5 bullets. Last bullet mentions "Update-available badges and version comparisons work again across every app." Hard-refresh (Cmd+Shift+R) if stale.
- Settings → App Registries: only
146.59.87.168:3000/lfg2025+git.tx1138.com. No .23. - Settings → System Update → Update Mirrors: only
.168(Server 1 primary) +tx1138(Server 2). No .23. - Install SearXNG (small, fast image). Expect: instant button response, 7 phase labels in progress bar (Preparing → Pulling image → Creating container → Starting container → Waiting for healthy → Finalizing → Done), Launch button appears within ~3s of "Done".
- Uninstall: snappy, no freeze.
Phase 2 — marketplace walk (app-by-app on .228)
Once Phase 1 is clean, user will install every app in the marketplace catalog one by one. Tracker: docs/MARKETPLACE-QA.md. For each broken app:
- Triage via
journalctl -u archipelago,podman ps -a,podman logs <name>. - Identify layer: app recipe / registry image / backend / frontend.
- Fix, commit
fix(app/<name>): ...or similar. - Redeploy as needed.
- Append release-note bullet for the fix (to current in-flight version, or bump to v1.7.44-alpha if the pile grows).
- User re-verifies, mark ✅ in the tracker.
Known pre-existing issue to expect: Vaultwarden container exits immediately on start. Backend correctly detects + removes state entry; needs container-config debug.
Overall mission (unchanged)
User mandate: "best server containers in the world". Polish install/uninstall/update flows for all 6 bundled server containers + marketplace apps before release. Tackle UX issues one by one in order.
Working layout — SSH + SSHFS
- SSHFS mount:
/Users/dorian/mnt/archy-thinkpad/→archy:Projects/archy/. Use for all file ops (read/edit/write/glob/grep). - Direct SSH:
ssh archy(=archipelago@192.168.1.116, ThinkPad dev). Use for git/cargo/npm/systemctl. - Demo node:
ssh archy228(=archipelago@192.168.1.228). NOPASSWD sudo. Dashboard login pw:password123. - Sudo pw on .116:
ThisIsWeb54321@. Fallback sudo pw on .228:archipelago. - Cargo:
~/.cargo/bin/cargoon .116. Long builds:nohup ... & disownto/tmp/cargo-build-*.log. - SSHFS flake:
writesometimes returnsNotFound: FileSystem.readFileon new files — retry once.
Deploy recipes
Backend binary (can't cp while running — "Text file busy"; binary ferries via Mac because .116 can't resolve archy228):
# On .116:
~/.cargo/bin/cargo build --release # ~3.5 min
# From Mac:
scp archy:Projects/archy/core/target/release/archipelago /tmp/archipelago-new
scp /tmp/archipelago-new archy228:/tmp/archipelago-new
ssh archy228 'sudo systemctl stop archipelago && sudo cp /tmp/archipelago-new /usr/local/bin/archipelago && sudo systemctl start archipelago && sudo systemctl reload nginx'
Frontend (rsyncs via Mac):
ssh archy 'cd ~/Projects/archy/neode-ui && npm run build' # outputs to ../web/dist/neode-ui/
rsync -az --delete archy:Projects/archy/web/dist/neode-ui/ /tmp/archy-web/
rsync -az /tmp/archy-web/ archy228:/tmp/archy-web/
ssh archy228 'sudo rsync -a --delete /tmp/archy-web/ /opt/archipelago/web-ui/ && sudo systemctl reload nginx'
Note: frontend source is neode-ui/ (has package.json). web/ has no package.json; web/dist/neode-ui/ is the build output.
Commit protocol
- Never push. User mirrors to Gitea remotes manually.
- Conventional Commits. No em-dashes or fancy punctuation.
- Multi-line messages via
tmp-commit-msg.txt:git commit -F tmp-commit-msg.txt && rm tmp-commit-msg.txt. - Git remotes on .116:
gitea-local,gitea-vps2(.168 OVH),tx1138(canonical),origin(multi-push alias)..23URLs were removed from origin andgitea-vpsremote was deleted — working-copy change, not in any commit.
Verification gates
cargo checkcargo test -p archipelago --bin archipelago <filter>(MUST use--bin archipelago; no lib target)cargo build --release
Known issues:
rust-lld: undefined hidden symbol→ cargo bug with test+release incremental collision. Fix:rm -rf core/target/debug/incrementaland retry.- 22 pre-existing
cargo testfailures in unrelated modules (mesh/wallet/credentials/avatar/session/transport/update-mirrors/fips/identity_manager/image_versions). Not blocking. Tech debt.
Architecture — locked-in patterns
Async-spawn lifecycle (install/update/uninstall/start/stop/restart)
- RPC returns
{status, package_id}immediately (15s client timeout). - Wrapper flips state to transitional variant (Installing/Updating/Removing/Stopping/Starting/Restarting) BEFORE spawn.
tokio::spawnruns existing monolithic inner handler withself: Arc<Self>.- Install/update success: MUST explicitly write terminal Running state.
merge_preserving_transitionalinserver.rsrefuses to let scanner overwrite transitional states. - Uninstall success: inner handler removes the entry itself.
- On error: revert pre-transition state (or remove entry for install).
Key files:
core/archipelago/src/api/rpc/package/async_lifecycle.rs— full install/update/uninstall wrapperscore/archipelago/src/api/rpc/transitional.rs— start/stop/restart wrapperscore/archipelago/src/server.rs:832-871—merge_preserving_transitional,is_transitionalcore/archipelago/src/server.rs:295-380— scan loop withtokio::select!and tick bump
Install progress (phase-based, 7 levels)
podman pullemits zero parseable progress when stderr is piped (no TTY). Legacy byte regex never matched.- Phases + UI %: Preparing (5) → PullingImage (20) → CreatingContainer (70) → StartingContainer (80) → WaitingHealthy (88) → PostInstall (95) → Done (100).
- UI bar only advances forward (
Math.max). - Final phase label is "Finalizing…" (renamed from "Running post-install…" which confused users).
Key files:
neode-ui/src/stores/server.ts:25-33—PHASE_INFOmapper
Scanner kick (instant Launch button)
- Scan runs every 60s. Post-install state flipped to Running but skeletal manifest (
interfaces: None) persisted until next scan →canLaunch(pkg)false for up to 60s. lan_addressderived from live container port bindings.manifest.interfaces.main.uionly populated whenlan_address.is_some() || tor_address.is_some().- Fix:
scan_kick: Arc<Notify>+scan_tick: Arc<watch::Sender<u64>>onRpcHandler. Scan looptokio::select!between 60s tick + notify.kick_scanner_and_waithelper (2s timeout) called in install/update success paths BEFORE writing Running. Merge during Installing keeps state + takes fresh manifest.
Key files:
core/archipelago/src/api/rpc/mod.rs:89-93— fields on RpcHandler; accessors :186-199core/archipelago/src/api/rpc/package/async_lifecycle.rs:405-430—kick_scanner_and_waitcore/archipelago/src/container/docker_packages.rs:132-218— wherelan_address+ manifest get populatedneode-ui/src/views/apps/appsConfig.ts:106-111—canLaunch(pkg)neode-ui/src/views/apps/AppCard.vue:141-149— Launch button render
Config migration (.23 auto-purge)
load_mirrors+load_registriesnormally only ADD missing defaults ("explicit removals stick").- .23 was a default the user never chose, so we need the opposite: strip it.
.retain(|m| !m.url.contains("23.182.128.160"))before defaults-merge step. Narrow-scope exception, commented in-code.- Triggers lazily on next load (install RPC, update RPC, Settings UI open). Not tied to boot.
Key files:
core/archipelago/src/container/registry.rs—load_registriescore/archipelago/src/update.rs—load_mirrors
Backlog — after v1.7.43 verification
- User reports browser-verification results. Fix anything that fails.
- Continue user's "one by one" install/uninstall/update UX queue — ask for next issue.
- Tech debt (low priority, not blocking release):
- Vaultwarden container exits immediately on start (separate container-config issue).
/var/log/archipelago-container-installs.lognever created — backend runs non-root. Tmpfiles.d rule or path change.- 22 pre-existing cargo test failures in unrelated modules.
- "Server 3 (OVH)" historical changelog entries in
AccountInfoSection.vueleft intact (user approved — they're release notes for what shipped at the time).
User preferences (must follow)
- Always state which option is "best long-term" first and explain why in plain terms. Trust my recommendation unless overridden.
- "Tackle them one by one in order" — fix issues sequentially, not in a big bang.
- Bitcoin-only. No altcoins, no proprietary deps without approval.
- Prefer established OSS, crypto-first libs (rustls, argon2, ed25519), privacy-focused (no telemetry), minimal dep trees.
- Atomic commits.
- Never commit secrets. Pin dependency versions.
- Never push — user mirrors to Gitea manually.