Files
archy/.planning/STATE.md
T
archipelagoandClaude Opus 5 f514ab515b docs(02-11): complete plan — leaked-poller fix, four-way verdicts, SUMMARY
Phase 02's last open item closed: web5/server/fleet fixed and proven
on archi-dev-box; app-details restored to at/near baseline;
discover's second cause (CSS entrance-animation replay on KeepAlive
reactivation) named and evidenced but not fixed, scoped as a
follow-up; openwrt-gateway not measurable this pass, prior numbers
flagged not retracted.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 09:37:54 -04:00

167 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
gsd_state_version: 1.0
milestone: v1.8.0
milestone_name: milestone
current_phase: 02
current_phase_name: ui-performance
status: verifying
stopped_at: Completed 02-11-PLAN.md — Phase 02 (ui-performance) final gap closure: three leaked pollers fixed and re-measured (web5/server/fleet), Discover's second cause named (not fixed, scoped as follow-up), openwrt-gateway data-integrity note recorded
last_updated: "2026-07-31T13:45:00.000Z"
last_activity: 2026-07-31
last_activity_desc: 02-11 gap closure complete — leaked background pollers fixed, four-way re-measure verdicts written
progress:
total_phases: 9
completed_phases: 2
total_plans: 28
completed_plans: 18
percent: 23
---
# Project State
## Project Reference
See: .planning/PROJECT.md (updated 2026-07-29)
**Core value:** A third-party developer can publish an app via the signed/decentralized registry and a user can install it on their node — manifest-driven, rootless, secure, robust.
**Current focus:** Phase 02 — ui-performance
## Current Position
Phase: 02 — gap closure complete (02-11 was the last open item)
Plan: 11 of 11 complete
Status: 02-11 complete — three leaked background pollers fixed and re-measured; Discover's second cause named, not fixed (scoped follow-up); openwrt-gateway unmeasurable this pass (browser crash), prior numbers stand with a data-integrity note
Last activity: 2026-07-31 — 02-11 gap closure complete
Progress: [███████░░░] 67%
## Performance Metrics
**Velocity:**
- Total plans completed: 0
- Average duration: —
- Total execution time: —
**By Phase:**
| Phase | Plans | Total | Avg/Plan |
|-------|-------|-------|----------|
| - | - | - | - |
**Per-Plan Metrics:**
| Plan | Duration | Tasks | Files |
|------|----------|-------|-------|
| Phase 02 P01 | 100min | 3 tasks | 5 files |
| Phase 02 P03 | 45min | 3 tasks | 5 files |
| Phase 02 P02 | 105min | 3 tasks | 11 files |
| Phase 02 P04 | 150min | 3 tasks | 12 files |
| Phase 02 P05 | 50min | 2 tasks | 8 files |
| Phase 02 P06 | 73min | 2 tasks | 7 files |
| Phase 02 P07 | 75min | 3 tasks | 5 files |
| Phase 02 P08 | ~190min | 3 tasks | 4 files |
| Phase 02 P09 | 130min | 3 tasks | 3 files |
| Phase 02 P10 | 55min | 2 tasks | 3 files |
| Phase 02 P11 | ~150min | 3 tasks | 8 files |
## Accumulated Context
### Roadmap Evolution
- Phase 1 added (2026-07-29): Federation & Mesh Hardening — user-directed top priority (node removal/sync issues, mesh attachment parity incl. demo); prior phases shifted down
- Phase 2 added (2026-07-29): UI Performance — slow tab switches and secondary screens; prior phases shifted down
- FED-05 added to Phase 1 (2026-07-29): inter-node Lightning channel-opening UX (share node URI, pick trusted/federated nodes by hostname, request channels with public nodes); UI tested on :8100 dev preview against archi-dev before deploy
- FED-06 added to Phase 1 (2026-07-29): on-brand paid-tick animation — screensaver ring + EQ segments (reuse ScreensaverRing.vue compact) replacing the success burst in SendBitcoinModal.vue
- Phase 9 added (2026-07-30): BotFights Platform Upgrade — native nostr signer login, unified AI bot-setup prompt replacing docs page, shared public match endpoint on VPS2 (all nodes see all fighters), registry/manifest update. Independent of Phases 18.
### Decisions
Decisions are logged in PROJECT.md (10 locked ADRs in the `<decisions>` block + milestone decisions table). Recent decisions affecting current work:
- Milestone version = 1.8.0-alpha (decided 2026-07-08)
- Phase-3 Quadlet default-flip is gated on the second-node gate reporting clean (do fresh, never stage uncommitted)
- Workstream D (DHT distribution) deferred to v2 — design-only backlog
- Canonical manifest schema = `core/container/src/manifest.rs` (code wins over spec doc)
- [Phase ?]: Marketplace is the 02-02 tracer tab (worst-measured main tab, 2033ms revisit) matching the user's own 'often app store' complaint
- [Phase ?]: ContainerAppDetails.vue confirmed fully unreachable dead code (no importer, no route) — no serial-RPC-waterfall target exists in the measured D-09 surface set
- [Phase ?]: archi-dev-box UI password was unknown/undiscoverable from this environment — paused at a checkpoint:human-action rather than guessing or falling back to a mock baseline silently
- [Phase ?]: Purged the resource cache on logout via clearAll() + a generation guard, so no in-flight fetch from an ending session can repopulate memory or sessionStorage (T-02-02)
- [Phase ?]: AppDetails/MarketplaceAppDetails/OpenWrtGateway converted to per-item (or single-key) keyed useCachedResource; CloudFolder.vue's existing store-level cache left as-is (cloud.ts TTL gate is a follow-up, out of this plan's file scope)
- [Phase ?]: Wallet/send flow (SendBitcoinModal.vue) reported as an unplanned-item gap — named by findings as owned by 02-03 but not in files_modified; its cost is pure client-side remount, not a caching problem
- [Phase ?]: PERF-03 reverted to Pending in REQUIREMENTS.md after an initial mark-complete was premature — its own text requires real-node-hardware verification, which is 02-08's job (also declares PERF-03); 02-03 delivers the code-level portion only
- [Phase ?]: 02-02: DashboardRouterView final shape uses statically-named per-route KeepAlive wrapper components (dashboardViewWrappers.ts) with :include name-matching, restoring pre-restructure view-wrapper DOM/animations byte-for-byte after a checkpoint-caught regression
- [Phase ?]: 02-02: HARD RULE for rest of Phase 02 — perf work must be visually invisible; verify against the real dev preview before considering a checkpoint satisfied
- [Phase ?]: 02-02: app-catalog persist:true ttl 300000ms; bitcoin.prune-status persist:true ttl 30000ms — both explicit per T-02-01, no default relied on
- [Phase ?]: 02-02: PERF-02 reverted to Pending/In-Progress in REQUIREMENTS.md after an automated mark-complete run — PERF-02 also spans 02-04..02-07 (extending KeepAlive caching to every remaining main tab); this plan proves the architecture on the tracer tab only
- [Phase ?]: 02-04: KEEP_ALIVE_PATHS widened to every audited main tab (10 paths) derived from TAB_ORDER + /dashboard/discover; /dashboard/settings deliberately withheld — its child sections (SystemDangerZone reboot poll, several onMounted-only fetches) were never audited by this plan
- [Phase ?]: 02-04: onActivated is a documented no-op outside a KeepAlive boundary — every arm function now runs from both onMounted and onActivated (fresh-mount guards on Home/Web5/Mesh/Server avoid doubling first-load RPC cost); caught by CloudPeersRefresh.test.ts
- [Phase ?]: 02-04: useCachedResource.ts's onActivated no longer eagerly force-loads a never-fetched immediate:false resource, so tab-gated lazy data (Cloud.vue Paid Files/My Files) isn't force-loaded merely by its view entering the KeepAlive cache
- [Phase ?]: 02-04: AIUI blank-screen-and-loading symptom reported at Task 3 checkpoint diagnosed as pre-existing (local mock-backend dev mode sets VITE_AIUI_URL=http://localhost:5173 unconditionally with no AIUI repo checked out) — not a regression, left for 02-07 (Chat/AIUI) to address
- [Phase ?]: 02-05: mesh.refreshAll()/transport.fetchStatus() stay uncached at the store level (other callers need guaranteed-fresh reads); the useCachedResource wrapper around each lives in Mesh.vue instead, since Pinia's defineStore(id,setup) runs in a bare effectScope where onActivated() silently no-ops
- [Phase ?]: 02-05: FLAGGED - RESEARCH.md's premise that Mesh.vue owns a D3 force simulation is incorrect for this codebase (verified via grep); only NetworkMap.vue/Federation.vue has one. Task 2's D3 truths are vacuously satisfied; only the real Leaflet map lifecycle (MeshMap.vue, added to scope) was implemented
- [Phase ?]: 02-05: per-group TTL/persist table - mesh.refresh-all/federation-nodes/self-onion/self-did/contacts all persist:false (identity payload); transport-status persists (aggregate, non-identity); reachability groups get 10s TTL, identity groups 300s
- [Phase ?]: 02-06: RESEARCH A3 settled — none of Server's seven load-group loaders consumes another's result; concurrent fan-out is correct as-is
- [Phase ?]: 02-06: Five of Server's seven groups were already on useCachedResource from a pre-phase legacy commit (ea254f63) with only composable defaults (30s TTL, persist:true) — this plan's work was explicit TTL/persist/dedup, not initial conversion; only loadDiskStatus was a genuinely uncached plain fetch
- [Phase ?]: 02-06: Home's wallet composite does NOT share a cache key with Web5.vue's web5.lnd-info — sharing would either corrupt Web5's typed entry.data or fail to close the sessionStorage gap since Web5.vue's own hook (out of scope) defaults persist:true
- [Phase ?]: 02-06: homeStatus.refresh() wrapped by useCachedResource at Home.vue (the view), not inside the homeStatus Pinia store — defineStore(id,setup) runs in a bare effectScope where onActivated() silently no-ops, same finding as 02-05's Mesh.vue
- [Phase ?]: 02-07: AIUI source located mid-plan at git.tx1138.com/lfg2025/AIUI (base branch development, not stale main); AIUI-side D-14 commit 900c0b9 initially local-only (anonymous push 403) then pushed/merged upstream onto development by the orchestrator using a user-supplied write token
- [Phase ?]: 02-07: D-14a fixed via new ?chatExpanded param overriding chat.ts's chatCollapsed default (never persisted to localStorage); D-14b fixed via new ?mobileChat param re-asserting ChatPage.vue's mobileTab='chat' once on mount, guarding against module-singleton content-panel state surviving an internal AIUI remount
- [Phase ?]: 02-07: PERF-02 marked Complete in REQUIREMENTS.md — 02-02 through 02-07 extended KeepAlive/useCachedResource to every main tab, each dev-preview-verified against archi-dev-box per D-11
- [Phase ?]: 02-08: KEEP_ALIVE_MAX left at 6, now backed by an on-device memory reading (4 cycles, 11 tabs, JS heap fluctuating 10-21MB, no monotonic growth) rather than the FA-D estimate
- [Phase ?]: 02-08: archy-x250-dev offline for the entire plan (checked 3x); archi-dev-box (D-11's named target) is the only dev-pair node this phase reached
- [Phase ?]: 02-08: the harness's remount-probe field is confounded for main tabs once real KeepAlive keeps multiple instances alive simultaneously; corrected via an independent, reproduced-twice verification rather than editing the frozen 02-01 harness — revealed Server.vue genuinely does not survive a round-trip (open gap, not hidden)
- [Phase ?]: 02-08: a user-reported Cloud first-visit navigation regression was treated as release-blocking, not known-open, per explicit direction — root-caused to content.browse-peer's unbounded, untimed-enough per-peer RPC fan-out starving Chromium's connection pool; fixed via a concurrency cap + shortened timeout, verified 5/5, user-approved on-node
- [Phase ?]: 02-08: 4 other user-reported UX issues (Paid Files window.open, PiP not closing lightbox, missing loader on Paid Files item-open, PiP not surviving tab changes) classified as pre-existing (predate phase 2 via git history) and captured into UIFIX-04/05/06, not fixed
- [Phase ?]: 02-09: /dashboard/server's (and Web5's) 'genuinely remounts' reading was a proven probe-measurement artifact (generic .view-container selector can't disambiguate the foreground tab from other still-connected cached tabs) — confirmed via document.elementFromPoint() hit-test contradicting the naive verdict across device runs; no source change needed, pinned with vm.$.uid-based regression tests instead
- [Phase ?]: 02-09: committed neode-ui/e2e/perf/keepalive-remount-probe.spec.ts as a re-runnable, instrumented probe covering every KEEP_ALIVE_PATHS tab, replacing the ad-hoc 02-08 probe so this class of false positive cannot recur
- [Phase ?]: [Phase 2, gap closure 02-10]: Wallet/send-flow's timing regression cleared as environmental noise (re-measure at/below baseline); Discover/Server/Web5/AppDetails/OpenWrtGateway confirmed as real, phase-2-caused client-side render/reactivation regressions via 3-run dispersion + git bisection, recorded as accepted deviations (not fixed — deploy blocked mid-session by a shared-tree hazard with concurrent security-follow-up and BotFights sessions)
- [Phase 2, gap closure 02-11]: Real cause of the six regressions was NOT compute-bound render cost (CPU profile: 86-99% idle/program, <10% JS self-time everywhere) — it was three background pollers (useFleetData.ts 60s, FipsNetworkCard.vue 15s, Web5Monitoring.vue 30s) armed in onMounted and never disarmed once their owning views joined KEEP_ALIVE_PATHS in 02-04, invisible to that audit because it grepped the top-level view files, not the child composables they delegate to. Gated to onActivated/onDeactivated, mirroring 02-04's own established pattern. Fixed: web5 275ms (was 566ms baseline/1329ms regressed), server 574ms (was 738/1239), fleet 790ms (was 330/2631)
- [Phase 2, gap closure 02-11]: Discover (1389ms, worst remaining) has a SECOND, distinct cause: card-stagger/showStagger entrance-animation classes are baked into the DOM at first mount and never programmatically removed, so every KeepAlive detach/reattach cycle restarts the CSS animation on reactivation — replaying the full entrance cascade on every revisit. Confirmed via a diagnostic (DOM card count doubling transiently on every revisit) and an extended animation-event log. NOT fixed — blast radius spans 5+ files outside 02-11's scope (Apps.vue, Marketplace.vue, Home.vue, several Web5 sub-cards), needs its own real-device verification budget; recommended as a dedicated follow-up
- [Phase 2, gap closure 02-11]: openwrt-gateway unmeasurable in the final re-measure (Chromium "Target crashed" cascading from an unrelated surface, cloud-folder, earlier in the same harness run) — recorded as not-measurable, not written in as data. Separately confirmed the prior baseline/after/remeasure numbers were measuring a real, substantive disconnected-state UI (OpenWrtGateway.vue's h1 is unconditional; a "No router configured" RPC error deterministically renders a real Connect-to-Router form, not a blank/error page) — the six-surface regression count is not retracted, but the numbers reflect one specific code branch (no OpenWrt device has ever been connected to archi-dev-box)
### Pending Todos
- [blocker/ui] Keep FIPS/Tor pills on cloud files and show them on mobile (`.planning/todos/pending/2026-07-30-keep-fips-tor-pills-on-cloud-files-and-show-them-on-mobile.md`)
- [blocker/security] Fedimint gateway must not install with a pre-set password — tracked as FED-07 / Phase 1 gap plan (`.planning/todos/pending/2026-07-30-fedimint-gateway-must-not-install-with-preset-password.md`)
- [blocker/ui] Connected-nodes list must scroll at row-matched height, not grow to fit (`.planning/todos/pending/2026-07-30-connected-nodes-list-must-scroll-at-row-matched-height.md`)
- [blocker/ui] Onboarding tickbox hidden below fold on short screens — make it beautifully obvious (`.planning/todos/pending/2026-07-30-onboarding-tickbox-hidden-below-fold-on-short-screens.md`)
- [major/ui] Paid Files pictures open in browser tab, not the app lightbox — UIFIX-04 (`.planning/todos/pending/2026-07-30-peer-files-pictures-open-in-tab-not-lightbox.md`)
- [major/ui] PiP should close the lightbox with a fluid animation — UIFIX-05 (`.planning/todos/pending/2026-07-30-pip-should-close-lightbox-with-fluid-animation.md`)
- [major/ui] Missing loader states on slow opens — UIFIX-06 (`.planning/todos/pending/2026-07-30-missing-loader-states-on-slow-opens.md`)
### Blockers/Concerns
- [Phase 1] Federation tombstone fix touches trust code — fix carefully, re-verify with `tests/multinode/smoke.sh`, don't patch blind
- [Phase 3] Multinode gate on archy-x250-beta was launched 2026-07-01 (log on-node); verify outcome before re-running
- [Phase 5] Fleet registry flip awaits explicit user authorization + timing call
- [Phase 6] Strengthened ADR-009 validation may reject existing catalog apps — audit manifests before enforcement lands
- [Global] Live OTA fleet: deploy to the dev pair before any OTA; gate re-runs required after orchestrator changes; some verification is user/hardware-gated (radios, on-device tests)
- cloud.ts's navigate() needs a TTL gate to fully satisfy 'no new RPC within TTL' for CloudFolder.vue — currently always re-fetches on revisit (just doesn't block paint)
- [Phase 2, RESOLVED by 02-09] ~~Server.vue does not survive a tab round-trip despite KEEP_ALIVE_PATHS registration~~ — retracted: proven a probe-measurement artifact (shared generic `.view-container` selector couldn't disambiguate the foreground tab from other cached tabs), not a real defect. Server.vue's (and Web5.vue's) instance genuinely survives; pinned with `vm.$.uid`-based regression tests immune to the same ambiguity. Checkpoint approved on real hardware.
- [Phase 2, RESOLVED by 02-11] ~~Timing regressions on Discover/Web5/Fleet/AppDetails/OpenWrtGateway~~ — root cause found (three leaked background pollers, not compute-bound render cost) and fixed for web5/server/fleet, each proven with a real before/after number on archi-dev-box. AppDetails restored to at/near its own pre-phase-2 baseline (pre-existing per-mount cost, not a new defect). OpenWrtGateway not measurable this pass (browser crash); prior numbers stand with a data-integrity note (measuring a real disconnected-device UI, not an empty page).
- [Phase 2, follow-up needed] Discover (1389ms, worst remaining named surface) has a second, evidenced, phase-2-caused defect: KeepAlive'd entrance-stagger animations (`card-stagger`/`showStagger`) never get their class removed from the DOM after first play, so every reactivation replays the full CSS animation cascade. Fix requires touching 5+ files outside 02-11's scope (Apps.vue, Marketplace.vue, Home.vue, Web5Wallet.vue/Web5Identities.vue/Web5NodeVisibility.vue/Web5NostrRelays.vue) with its own real-device visual-regression verification budget (the same class of risk 02-02's original KeepAlive rollout hit on its first checkpoint attempt) — needs a dedicated follow-up plan, not squeezed into a gap-closure pass.
### Quick Tasks Completed
| # | Description | Date | Commit | Directory |
|---|-------------|------|--------|-----------|
| 260729-fw7 | improve mesh message hop graphic/animation: balanced desktop sizing, vertical mobile layout, archipelago branding | 2026-07-29 | ac09fc5d | [260729-fw7-improve-mesh-message-hop-graphic-animati](./quick/260729-fw7-improve-mesh-message-hop-graphic-animati/) |
| 260729-gjd | demo: indee.tx1138.com in app iframe (:2101 whole-origin proxy), auto nostr signer sign-in, IndeeHub pre-installed on fresh session | 2026-07-29 | d00ca624 | [260729-gjd-demo-make-indee-tx1138-com-work-in-the-a](./quick/260729-gjd-demo-make-indee-tx1138-com-work-in-the-a/) |
| 260729-hj1 | peer-files media batch: Wavlake paid tracks + purchases + dedupe + real photos (demo); lightbox/player open routing + free-image lightbox fix (both builds) | 2026-07-29 | f52c5407 | [260729-hj1-peer-files-media-batch-wavlake-paid-trac](./quick/260729-hj1-peer-files-media-batch-wavlake-paid-trac/) |
| 260729-je5 | connected-nodes list fills card height (constant footer gap); companion app skips demo intro | 2026-07-29 | d54517cf | [260729-je5-ui-fixes-connected-nodes-scrollable-list](./quick/260729-je5-ui-fixes-connected-nodes-scrollable-list/) |
## Deferred Items
| Category | Item | Status | Deferred At |
|----------|------|--------|-------------|
| Distribution | DIST-01 DHT/iroh backbone (workstream D) | v2 | 2026-07-29 |
| Fleet | FLEET-01 Bitcoin multi-version fleet OTA (user-gated) | v2 | 2026-07-29 |
| Fleet | FLEET-02 per-app deep health assertions (~34 apps) | v2 | 2026-07-29 |
| Fleet | FLEET-03 LUKS2 data-partition encryption | v2 | 2026-07-29 |
## Session Continuity
Last session: 2026-07-31T13:45:00.000Z
Stopped at: Completed 02-11-PLAN.md — Phase 02 (ui-performance) final gap closure complete
Resume file: None