Archipelago — open-source initial import
This commit is contained in:
+23
@@ -0,0 +1,23 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: Connected-nodes list must scroll at row-matched height, not grow to fit
|
||||
area: ui
|
||||
severity: blocker
|
||||
files:
|
||||
- neode-ui/src/views/web5/Web5ConnectedNodes.vue
|
||||
- neode-ui/src/views/web5/Web5.vue
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian reports (2026-07-30): the connected-nodes container's inner list was still meant to scroll, and currently it doesn't — it grows to fit all rows without a scrollbar. The intended behavior for the row layout:
|
||||
|
||||
- The connected-nodes container sits in a row next to another container (on the right).
|
||||
- If the right-hand container is TALLER, the connected-nodes inner list should extend/scale to match the right container's height.
|
||||
- Within that matched height the list must remain SCROLLABLE when it has more rows than fit — it must NOT expand to show all entries scroll-free (which stretches the row).
|
||||
|
||||
So: height is driven by the sibling (equal-height row), overflow inside is `scroll`, never grow-to-fit. Likely component: `Web5ConnectedNodes.vue` inside `Web5.vue`'s row layout (verify — "connected nodes" also appears in settings AccountInfoSection). This sounds like a regression/misimplementation of an earlier request ("was still meant to scroll").
|
||||
|
||||
## Solution
|
||||
|
||||
Classic equal-height-row + inner-scroll pattern: the row uses flex with stretch alignment; the connected-nodes card gets `min-height: 0` (or `h-full` with a min-h-0 flex column) and the inner list `flex-1 overflow-y-auto`, so its height tracks the taller right-hand sibling while the list scrolls internally. Confirm exact container with Dorian's screenshot/preview if ambiguous. Standing rule: change only this behavior — no other visual changes.
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: Fedimint gateway must not install with a pre-set password
|
||||
area: security
|
||||
severity: blocker
|
||||
files:
|
||||
- core/archipelago/src (app orchestrator / secrets materialisation)
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian reports (2026-07-30): the Fedimint gateway app installs with a password already set up — i.e. a default/pre-baked credential rather than one generated at install time or set by the user. Default credentials on a Lightning/fedimint gateway are a security hole: anyone knowing the shipped default can access the gateway. Dorian rated this a blocker.
|
||||
|
||||
This also violates the repo's standing secrets invariant (CLAUDE.md): secrets must be manifest-declared (`generated_secrets`, materialised by `container::secrets`, 0600/rootless) — never hardcoded or per-app baked in.
|
||||
|
||||
## Solution
|
||||
|
||||
Tracked as requirement **FED-07** (Phase 1, ROADMAP success criterion 7 — needs a gap plan since phase 1's 10 plans predate it):
|
||||
- Find where the fedimint gateway app's manifest/install path sets its password (check `/opt/archipelago/apps/*/manifest.yml` for the gateway, and the orchestrator's secrets materialisation).
|
||||
- Move it to `generated_secrets` so each install gets a unique credential, or require explicit user setup.
|
||||
- Migration path for existing installs still carrying the default password (migrations must never destroy data).
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: Keep FIPS/Tor pills on cloud files and show them on mobile
|
||||
area: ui
|
||||
severity: blocker
|
||||
files:
|
||||
- neode-ui/src/views/Cloud.vue
|
||||
- neode-ui/src/views/CloudFolder.vue
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian loves the FIPS/Tor pills shown on cloud files ("really helpful") — they must be kept and never removed in any future cleanup or refactor. However, they do not (or may not) display on mobile widths, where they are hidden or cramped. Dorian rated mobile visibility a blocker: on mobile, users genuinely can't see the security/transport state of their files.
|
||||
|
||||
Context: captured 2026-07-30 during phase 02 (ui-performance) execution. The pills live in the Cloud file listing UI (Cloud.vue / CloudFolder.vue area — verify exact component when picking this up).
|
||||
|
||||
## Solution
|
||||
|
||||
Ensure the FIPS/Tor pills render at mobile breakpoints in the cloud file views — likely responsive-layout work (wrap/stack/compact-pill variant) rather than new functionality. Must follow the standing rule: no changes to existing desktop visuals/animations — mobile-only additions. TBD exact approach after inspecting the component at mobile widths.
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: Migrate all VPS2 references to https://source.archipelago-foundation.org (stop exposing IP; TLS everywhere)
|
||||
area: security
|
||||
severity: blocker
|
||||
files:
|
||||
- apps/*/manifest.yml
|
||||
- app-catalog/catalog.json
|
||||
- neode-ui/public/catalog.json
|
||||
- core/archipelago/src (update.rs, container/registry.rs, image_versions.rs, image_policy.rs, quadlet.rs, prod_orchestrator.rs, app_catalog.rs, companion.rs, api/rpc/package/*)
|
||||
- core/container/src/podman_client.rs
|
||||
- core/archipelago/src/fips/anchors.rs
|
||||
- scripts/self-update.sh
|
||||
- scripts/first-boot-containers.sh
|
||||
- scripts/create-release.sh
|
||||
- scripts/create-release-manifest.sh
|
||||
- scripts/image-versions.sh
|
||||
- scripts/generate-app-catalog.sh
|
||||
- scripts/bootstrap-switchover.sh
|
||||
- release-manifest.json
|
||||
- releases/manifest.json
|
||||
- tests/lifecycle/remote-lifecycle.sh
|
||||
- .gitea/workflows/demo-images.yml
|
||||
- neode-ui/src/components/CompanionIntroOverlay.vue
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian (2026-07-30, CRITICAL): every VPS2 service is referenced by raw IP `146.59.87.168` — plain HTTP for most — exposing the IP in shipped artifacts and requiring insecure-registry config on every node. Everything must move to `https://source.archipelago-foundation.org` "perfectly so all the stuff we use it for works".
|
||||
|
||||
**Verified inventory (2026-07-30):** ~196 references.
|
||||
- `:3000` (Gitea — git/raw/releases AND the OCI container registry): **194 refs** — every app manifest's `image:` field, both catalogs (app-catalog/catalog.json + neode-ui/public/catalog.json, 23 each), compiled Rust core (self-update, registry allow-list, image policy/versions, quadlet gen, package RPCs, podman client), OTA manifests (release-manifest.json, releases/manifest.json), lifecycle tests, release/first-boot/self-update scripts, CI workflows, docs, UI marketplace data.
|
||||
- `:2100` (companion APK package server): 1 ref (`CompanionIntroOverlay.vue`).
|
||||
- `:8444` (FIPS trust anchor, raw TLS — `ARCHY_ANCHOR_ADDR` in `fips/anchors.rs`): 1 ref.
|
||||
|
||||
**Domain coverage verified live (2026-07-30):**
|
||||
- git clone/ls-remote over HTTPS: ✓ (works; `gitea-ai` remote already switched)
|
||||
- Gitea raw + releases: ✓ (HTTP 200)
|
||||
- Container registry `/v2/` through the domain: ✓ (proper 401 auth-challenge; TLS pulls will work and the insecure-registry hack becomes removable)
|
||||
- `:2100` APK server: ✗ NOT behind the domain — needs an openresty route/subdomain on VPS2 (Dorian/VPS2-side)
|
||||
- `:8444` FIPS anchor: ✗ raw TLS service, can't share 443 — at minimum switch the constant to a DNS name (e.g. anchor host + :8444); check whether anchors pin certs before touching (security-sensitive)
|
||||
|
||||
## Solution
|
||||
|
||||
Execute as a dedicated quick task IMMEDIATELY AFTER phase 2's 02-08 (don't disturb the dev-pair perf measurements; requires core Rust rebuild + node verification per CLAUDE.md discipline):
|
||||
1. Mechanical rewrite of all `:3000` refs → `https://source.archipelago-foundation.org` (registry image refs become `source.archipelago-foundation.org/lfg2025/<img>:<tag>` — no port, implies 443/TLS).
|
||||
2. **Image-ref transition safety:** running containers/quadlets store the OLD image name; migration must not orphan or re-pull-break existing apps (migrations never destroy data). Plan the transition: catalog+manifests flip, orchestrator treats old/new registry names as equivalent during adoption, or staged re-tag.
|
||||
3. Rebuild core, run the lifecycle gate on a dev node (NOT the fleet), verify: self-update fetch, catalog fetch, image pull via domain, app install end-to-end.
|
||||
4. Keep the IP endpoints alive on VPS2 during transition — nodes updating FROM old releases still hit IP URLs (fallback window until fleet rolls past).
|
||||
5. `:2100` + `:8444`: Dorian is setting these up (2026-07-30) as:
|
||||
- `companion.archipelago-foundation.org` → replaces `http://146.59.87.168:2100` (companion APK downloads; update `CompanionIntroOverlay.vue` + any packaging docs). HTTPS assumed — verify before flipping.
|
||||
- `fips.archipelago-foundation.org` → replaces the raw IP in `ARCHY_ANCHOR_ADDR` (`fips/anchors.rs`), becoming `fips.archipelago-foundation.org:8444` (or whatever port Dorian lands on). SECURITY-SENSITIVE: check whether the FIPS anchor validation pins certificates/identity to the address before changing; verify anchor handshake against the new name from a dev node before fleet rollout.
|
||||
- As of 2026-07-30 22:50 UTC neither subdomain resolved yet — re-verify DNS + TLS at execution time; do not flip these two refs until both probes pass.
|
||||
6. Remove insecure-registry config from node provisioning once pulls verify over TLS.
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: Add loader states to surfaces that take time to open
|
||||
area: ui
|
||||
severity: major
|
||||
files:
|
||||
- neode-ui/src/views (inventory needed — which opens are slow with no loading affordance)
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian (2026-07-30): "some stuff doesn't have loader states when it's gonna take time to open" — certain screens/actions with genuinely slow opens give no loading feedback, so the UI feels dead/broken while working.
|
||||
|
||||
## Solution
|
||||
|
||||
Inventory slow-open surfaces (02-08's PERF-AFTER timings + the flagged timing regressions are a starting list: Discover, Server, Web5, Fleet, AppDetails, OpenWrtGateway); add house-style skeletons/spinners where an open can exceed ~300ms, consistent with the phase 2 rule that cached revisits show no spinner. Clearest confirmed instance (02-08 classification, pre-existing since 2026-07-22): `Cloud.vue` `viewPaidItem()`'s `content.owned-get` call has a 60s timeout and zero loading indicator. `CloudFolder.vue`'s native file grid already has a skeleton (fine). Tracked as UIFIX-06 (phase 1).
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: Onboarding tickbox hidden below fold on short screens — make it beautifully obvious
|
||||
area: ui
|
||||
severity: blocker
|
||||
files:
|
||||
- neode-ui/src/views/OnboardingSeedGenerate.vue
|
||||
- neode-ui/src/views/OnboardingWrapper.vue
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian reports (2026-07-30): on shorter screens, the onboarding screen's tickbox (the seed-phrase confirmation checkbox in `OnboardingSeedGenerate.vue` — verify it's this step) sits below the fold inside a scrollable area, and it's not obvious it exists — users don't realize they need to scroll to find it, so onboarding appears stuck. Blocker: this stalls new-user onboarding on small displays.
|
||||
|
||||
## Solution
|
||||
|
||||
Make its presence obvious "in a beautiful way" (Dorian's words — design discretion, but it must feel intentional and match the house glass/dark style, not a bolted-on arrow). Candidate approaches to evaluate:
|
||||
- A soft bottom scroll-affordance: gradient fade at the container's bottom edge plus a subtle animated chevron/pulse when unscrolled content remains, disappearing once the tickbox is in view.
|
||||
- Or make the tickbox + continue button a sticky footer of the card on short viewports so it's always visible, with the seed content scrolling behind it.
|
||||
- Or auto-scroll/nudge the container after the seed is revealed.
|
||||
|
||||
Constraints: follow the standing rule — don't alter the existing onboarding look beyond this affordance; keep desktop/tall-screen appearance unchanged; whatever ships must be verified on an actual short viewport (e.g. small laptop / mobile landscape).
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: Paid Files pictures open in a browser tab instead of the app lightbox
|
||||
area: ui
|
||||
severity: major
|
||||
files:
|
||||
- neode-ui/src/views/Cloud.vue (Paid Files sub-tab — locate the picture click handler)
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian (2026-07-30, on archi-dev-box; initially said "peer files", corrected to **Paid Files**): in the Cloud tab's Paid Files section, clicking a picture opens it in a new browser tab rather than the in-app lightbox that exists elsewhere ("the lightbox we've made"). Inconsistent media UX.
|
||||
|
||||
## Solution
|
||||
|
||||
Route Paid Files image clicks through the existing lightbox component. Classified by 02-08 (pre-existing, introduced f3393581 2026-07-22): `Cloud.vue`'s `viewPaidItem()` (~line 470) calls `window.open(...)` instead of routing into `MediaLightbox.vue`. Fix: invoke MediaLightbox the way My Files does. Tracked as UIFIX-04 (phase 1).
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
created: 2026-07-30T22:19:31.770Z
|
||||
title: PiP robustness — close lightbox fluidly, survive tab changes and buffering
|
||||
area: ui
|
||||
severity: major
|
||||
files:
|
||||
- neode-ui/src (lightbox/video player components — locate exact files)
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian (2026-07-30), two reports:
|
||||
1. Entering picture-in-picture on a video does not close the lightbox — it should close with a fluid on-brand animation as PiP begins.
|
||||
2. "Picture in picture must survive tab changes or video buffering pauses, doesn't seem to, please fix." — PiP currently dies when switching main tabs and/or when the video pauses to buffer.
|
||||
|
||||
Classified by 02-08 (all pre-existing, NOT phase 2): `src/utils/pip.ts`'s `togglePip()` (introduced f72d4b92 2026-07-23) never touches `MediaLightbox.vue`'s visibility state; no `onDeactivated` teardown exists in Cloud/CloudFolder/MediaLightbox (phase 2 added none there); pre-phase-2 tab switches fully unmounted the view, so PiP tab-survival never existed. The `<video>` has zero pause/waiting/stalled listeners — buffering behavior is pure native. KeepAlive actually helps now: the element persists off-screen, so survival is achievable by not letting anything pause/unmount it.
|
||||
|
||||
## Solution
|
||||
|
||||
- PiP enter → close the lightbox with a house-style fluid animation (handoff feel).
|
||||
- While PiP is active: the owning video element must not be paused/reset/unmounted by tab deactivation — exempt media playback from deactivate teardown when `document.pictureInPictureElement` is the view's video (or reparent the video to a persistent host).
|
||||
- Buffering (`waiting` events / `pause` from buffering) must not close PiP or the session — only explicit user stop should.
|
||||
Tracked as UIFIX-05 (phase 1 gap plan).
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
created: 2026-07-31T19:00:00.000Z
|
||||
title: Build the installer ISO for v1.7.119-alpha
|
||||
area: tooling
|
||||
severity: minor
|
||||
files:
|
||||
- scripts/build-iso-release.sh
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
v1.7.119-alpha is released and its OTA assets are published and checksum-verified, but the **installer ISO was never built**. Three attempts were blocked by a dirty working tree — `build-iso-release.sh`'s preflight hard-fails on any uncommitted change, and this checkout is shared by phase 1 executors and a separate BotFights session, so the tree is rarely clean for long. Not urgent: the ISO only matters for fresh installations; everyone updating is served by the working OTA.
|
||||
|
||||
## Solution
|
||||
|
||||
Run during a genuine pause in phase 1 execution (between waves), not racing against it:
|
||||
|
||||
```
|
||||
TMPDIR=/home/archipelago/tmp/iso-scratch bash scripts/build-iso-release.sh
|
||||
```
|
||||
|
||||
Keep the QEMU boot test (no `--no-qemu`).
|
||||
|
||||
**Preconditions:** `git status --porcelain` empty on `main`.
|
||||
|
||||
**Launch it as an explicit background job.** The build runs well past 10 minutes; twice it hit the tool's foreground timeout and once that killed an in-progress `cargo test` outright.
|
||||
|
||||
**Build from current `main` HEAD, not a detached tag checkout** — decision already made, don't re-derive. Preflight requires `git rev-parse --abbrev-ref HEAD == "main"` (a detached checkout returns `HEAD` and fails), and the archipelago version identity (Cargo.toml / package.json / CHANGELOG / manifest, all `1.7.119-alpha`) is untouched by commits made after the tag. BotFights is versioned and shipped independently via the signed catalog, so building at HEAD ships the security-fixed 1.2.11 rather than reverting to the vulnerable 1.2.9 current at tag time.
|
||||
|
||||
**Gates already seen passing** (mostly cached, expect them to pass fast): git-diff-check, cargo-fmt, catalog-drift, whats-new-sync, ui-type-check, ui-unit-tests (788), cargo-check. **Not yet reached:** cargo-test-weekly (~1500s), verify-artifacts, build-iso, iso-smoke, qemu-boot.
|
||||
|
||||
`TMPDIR` matters while `/tmp` (12G tmpfs) is tight — honored natively by mktemp-based scripts and by `test-iso-qemu.sh` since commit `6c2b6668` fixed its hardcoded `/tmp` paths.
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
created: 2026-08-01T04:05:00.000Z
|
||||
title: Make archi-dev-box double as a fresh test node (both shapes, no ISO flash)
|
||||
area: testing-infra
|
||||
severity: major
|
||||
files:
|
||||
- core/archipelago/src/config.rs (the env seams: ARCHIPELAGO_DATA_DIR:125, ARCHIPELAGO_BIND:129, ARCHIPELAGO_PORT_OFFSET:155, ARCHIPELAGO_APPS_DIR)
|
||||
- core/container/src/port_manager.rs (port_offset applied at :44)
|
||||
- core/archipelago/src/auth.rs (:182 is_onboarding_complete — "fresh" is decided purely from state inside data_dir)
|
||||
- tests/lifecycle/ (existing gate harness — candidate host for the new node profile)
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
Dorian (2026-08-01): wants archi-dev-box to serve as a testing node that can be exercised
|
||||
"as if it's a new node", running alongside the existing Linux desktop app install, **without
|
||||
flashing the ISO**. Both shapes are wanted — this is a testing node, so it needs to cover
|
||||
first-run UX *and* real app lifecycle.
|
||||
|
||||
Today the box runs one real production-ish node: `archipelago.service` (systemd, enabled,
|
||||
`/usr/local/bin/archipelago`) against a heavily-populated `/var/lib/archipelago` (bitcoin,
|
||||
btcpay, botfights, blobs, live LND/mesh state). That node must not be disturbed — it is the
|
||||
dev-pair deploy target gated before every OTA.
|
||||
|
||||
## Solution
|
||||
|
||||
Two shapes, both ISO-free. Ship A first, then B.
|
||||
|
||||
**(A) Lightweight second instance, same Linux user.** Own empty `ARCHIPELAGO_DATA_DIR`, own
|
||||
`ARCHIPELAGO_BIND` port, `ARCHIPELAGO_PORT_OFFSET` set, mesh/Reticulum disabled. Boots
|
||||
un-onboarded, so it exercises the true first-run path: seed generation, password/setup,
|
||||
identity keygen, node naming, onboarding UI. Cheap to create and destroy — the natural
|
||||
regression harness for onboarding changes.
|
||||
|
||||
**(B) Second Linux user** (`useradd` + `loginctl enable-linger` + its own rootless podman
|
||||
namespace + own data dir). Gives a genuinely independent node where app install / uninstall /
|
||||
reinstall lifecycle is real, not shared. This is what makes it a *testing node* rather than a
|
||||
first-run mock.
|
||||
|
||||
## Hazards (verified by grep 2026-08-01, must be designed around)
|
||||
|
||||
1. **Hardcoded paths defeat `ARCHIPELAGO_DATA_DIR`.** Several constants point at
|
||||
`/var/lib/archipelago` literally and ignore the override: `bitcoin_rpc.rs:10`
|
||||
(`SECRETS_PATH`), `container/lnd.rs:131` (`ARCHY_DATA_DIR`), `electrs_status.rs:15`,
|
||||
`api/rpc/package/pine_ha.rs:34-36`, `bootstrap.rs:242` (secrets dir), `disk_monitor.rs:41`.
|
||||
Under shape (A) a test instance that installs **Bitcoin, LND, electrumx, or Pine/HA would
|
||||
read and write the LIVE node's files.** Those four are off-limits in (A); shape (B) fixes
|
||||
this properly via a different user's paths — or the constants get plumbed through config,
|
||||
which is arguably the real fix and a candidate follow-up.
|
||||
2. **Rootless podman is per-Linux-user.** In (A) both instances share one container
|
||||
namespace: `PORT_OFFSET` resolves port collisions, container *name* collisions it does not.
|
||||
3. **Reticulum/mesh contention.** The live daemon holds `/dev/mesh-radio` and
|
||||
`identity/node_key`; a second instance would fight it for the radio. Mesh must be off for
|
||||
the test node (or the radio explicitly assigned to one of them).
|
||||
|
||||
## Notes
|
||||
|
||||
Raised while resuming quick task 260731-upz (entropy/seed audit) — shape (A) is also the
|
||||
natural on-node harness for that audit's UNVERIFIED checklist, since fresh-seed generation is
|
||||
exactly the `[ARCHY-1]` path under review. Sequence this after 260731-upz lands.
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
---
|
||||
created: 2026-08-01T09:45:00.000Z
|
||||
title: Verify FED-07 gateway credential rotation on a real node (01-16 Task 2)
|
||||
area: security
|
||||
severity: major
|
||||
files:
|
||||
- core/archipelago/src/container/secrets.rs
|
||||
- core/archipelago/src/container/prod_orchestrator.rs
|
||||
- .planning/phases/01-federation-mesh-hardening/01-16-PLAN.md
|
||||
---
|
||||
|
||||
## Problem
|
||||
|
||||
FED-07's code is complete and pushed (`42652547` removed every shipped credential,
|
||||
`9e2d2ef2` added detection + rotation for nodes already carrying one), but **plan 01-16's
|
||||
blocking Task 2 checkpoint has never been run**, so the requirement is not closed. Two
|
||||
things are unproven:
|
||||
|
||||
1. **That the recreate actually preserves the gateway's data.** Rotation deliberately
|
||||
avoids any teardown: it changes the credential, which changes `secret_env_hash`, which
|
||||
the drift check reads as a container-label mismatch, which fires the platform's own
|
||||
recreate around the unchanged data directory, ports, volumes and container name. That
|
||||
chain is confirmed by reading the code (`prod_orchestrator.rs:3309` computes the hash,
|
||||
`:3374` compares the label) but has **never been observed running**.
|
||||
2. **That the rotated credential actually authenticates** and the old shipped one is
|
||||
rejected.
|
||||
|
||||
## Why it was deferred (2026-08-01)
|
||||
|
||||
Checkpoint step 1 was run read-only on archi-dev-box. Findings:
|
||||
|
||||
- **The node is CLEAN** — the hash file is present, `600`, `archipelago:archipelago`, and
|
||||
is *not* the shipped default. The legacy `fedimint-gateway-password` file also exists.
|
||||
- **There is no `fedimint-gateway` container.** The app is installed at
|
||||
`/opt/archipelago/apps/fedimint-gateway`, but nothing is running and
|
||||
`/var/lib/archipelago/fedimint-gateway` is empty. `archy-fedimint-ui` and
|
||||
`fedimint-clientd` are running, but they are not the gateway.
|
||||
|
||||
So the rotation path cannot fire naturally here, and steps 5–6 (data survived, gateway
|
||||
authenticates) have nothing to exercise. Proving it on this box means installing and
|
||||
starting the gateway first, then deliberately seeding the old value — which the plan's
|
||||
Planner Assumption already anticipates and requires be recorded.
|
||||
|
||||
The deploy itself is the blocker: **30 containers are running with 4–8 days uptime**
|
||||
(IndeeHub relay/minio/postgres/ffmpeg, Immich, BTCPay + nbxplorer, netbird, portainer,
|
||||
strfry, searxng, the archy UI set), the `archipelago` system service is active, and
|
||||
CLAUDE.md's standing rule is that restarting it SIGKILLs containers until Quadlet is the
|
||||
default. Step 8 then wants `tests/lifecycle/run-gate.sh` on the same box, which cycles
|
||||
install/stop/start/reinstall/reboot-survive. Dorian chose to hold rather than take that
|
||||
blast radius unattended.
|
||||
|
||||
## Solution
|
||||
|
||||
Run 01-16 Task 2's eight steps in a window where restarting `archipelago` on the target is
|
||||
acceptable. Two viable routes:
|
||||
|
||||
- **On archi-dev-box:** install + start `fedimint-gateway`, put some state in its data
|
||||
directory, seed the old hash into
|
||||
`/var/lib/archipelago/secrets/fedimint-gateway-hash`, deploy this build, restart, then
|
||||
run steps 3–8. Record that the affected state was seeded deliberately.
|
||||
- **On a node that runs the gateway for real** (.228 is the heavy 14-app node): the
|
||||
rotation path may exist naturally there, which is stronger evidence than seeding.
|
||||
|
||||
Either way, record in `01-16-SUMMARY.md`: the affected-or-clean verdict, the exact deploy
|
||||
command, whether the `secret_env_hash` recreate was observed firing, the gate result, and
|
||||
the fact that archy-x250-dev was offline (single-node verification with the second-node
|
||||
gap recorded honestly is the expected pattern).
|
||||
|
||||
## Related, found while doing 01-16
|
||||
|
||||
- **Operator recovery gap:** `handle_package_credentials`
|
||||
(`core/archipelago/src/api/rpc/package/install.rs:2093`) is a hardcoded if-chain covering
|
||||
only `filebrowser` and `photoprism`. `fedimint-gateway` falls through to an empty list,
|
||||
so after a rotation the operator has no in-UI way to get the new password — only the
|
||||
`0600` file the log line names. Adding one arm closes it; the UI already renders whatever
|
||||
the RPC returns.
|
||||
- **`apps/photoprism/manifest.yml:35` ships `PHOTOPRISM_ADMIN_PASSWORD=archipelago`**, and
|
||||
that same literal is handed to the UI. Same defect class as FED-07 on a different app —
|
||||
wants its own requirement.
|
||||
</content>
|
||||
Reference in New Issue
Block a user