23 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, requirements-completed, coverage, duration, completed, status
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | requirements-completed | coverage | duration | completed | status | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 02-ui-performance | 08 | ui |
|
|
|
|
|
|
|
|
~3h10min (includes one human-action checkpoint pause for the archi-dev-box credential, one human-verify checkpoint round-trip with two follow-up investigation/fix cycles) | 2026-07-30 | complete |
Phase 02 Plan 08: Dev-Pair Deploy, On-Device Re-Measure, D-11 Pass Bar Summary
Deployed the full phase to archi-dev-box, re-measured every surface with the same harness and target as the baseline (uncovering and correcting a remount-probe confound the new KeepAlive architecture exposed), confirmed KEEP_ALIVE_MAX=6 from an on-device memory reading, and closed a real first-visit connection-pool-starvation regression found during the human pass bar — content.browse-peer's unbounded, untimed per-peer fan-out, not the router or the click handler.
Performance
- Duration: ~3h10min (Task 1 build+deploy+memory-tuning, a human-action checkpoint pause for the archi-dev-box password, Task 2 re-measurement, and a Task 3 checkpoint round-trip with two full investigation-and-fix cycles for a user-reported regression)
- Completed: 2026-07-30
- Tasks: 3/3 completed (Task 3 is the plan's checkpoint:human-verify, approved)
- Files modified: 3 (1 artifact created, 2 source files modified across 6 substantive commits)
Accomplishments
- Deployed this phase's frontend (and confirmed AIUI's already-current
development-branch build) to archi-dev-box viaARCHIPELAGO_TARGET=archipelago@archi-dev-box scripts/deploy-to-target.sh --frontend-only— this machine (the ThinkPad build server) is archi-dev-box itself, confirmed via Tailscale MagicDNS.archy-x250-dev, the dev pair's second node, was checked and found offline at three separate points across the plan and never came back; only archi-dev-box received this phase's build, which is what D-11 names as the verification target. - Confirmed the built bundle was genuinely current (not a stale/no-op build) by grepping the served asset (
/opt/archipelago/web-ui, not just the localweb/distcopy) for representative strings from every plan in the phase. - Tuned
KEEP_ALIVE_MAXfrom a real on-device Chromium heap reading (CDPPerformance.getMetrics) instead of leaving the carried-forward estimate unexamined: 4 full two-way cycles through all 11 main tabs showed the heap fluctuating 10-21MB with no monotonic growth — confirmed the cap at 6 is genuinely bounding memory, not sitting unused. Left unchanged, now measurement-backed. - Re-ran the plan 02-01 harness unmodified against archi-dev-box, producing
02-PERF-AFTER.json(15/15 rows, matching the baseline's row count) and appending02-FINDINGS.md's## Results/## Outstandingsections. - Discovered and corrected a harness-methodology confound this run exposed for the first time: the remount probe's generic
.view-containerselector — unambiguous pre-phase-2 when only one view was ever mounted — becomes ambiguous once real KeepAlive keeps multiple main-tab instances alive simultaneously. Rather than editing the frozen harness, independently re-verified every main tab's true remount status with a corrected, reproduced-twice method: Home/Apps/Marketplace/Cloud/Web5/Fleet genuinely survive a round-trip; Server genuinely does not — recorded as an open, unfixed gap rather than smoothed over. - Recorded real timing regressions (Discover, Server, Web5, Fleet, AppDetails, OpenWrtGateway) honestly per the plan's own prohibition against averaging them away, with a same-time-of-day-variance caveat noted for interpretation, not used to soften any verdict.
- Found, root-caused, and fixed a genuine real-hardware regression during the Task 3 checkpoint: a user-reported "first visit to Cloud, no folder opens on click" was proven — via direct instrumentation (a raw DOM click listener, a patched live
$routerinstance, request-lifecycle tracking, and manualimport()calls from the page console) — to be a downstream symptom of Chromium's per-origin connection pool being starved by 13 of 14 concurrent, permanently-pendingcontent.browse-peerRPCs to dead/unreachable peers, not a router or click-handler bug. Closed across two commits: a fresh-mount guard onCloud.vue's dualonMounted/onActivatedfire (necessary but insufficient alone), then a concurrency cap (3) + shortened timeout (10s) on the peer-browse fan-out itself, mirroringPeerFiles.vue's existingPREVIEW_CONCURRENCYpattern. Verified 5/5 fresh sessions navigate cleanly, zero in-flight hung requests after 15s on Cloud, and a previously-permanently-hung route chunk import now resolves in 17ms. User's final on-node re-check: approved. - Classified four other user-reported UX issues via git history against the pre-phase-2 baseline commit (
a75b6709) and confirmed all pre-existing, not phase-2 regressions, with exact file/line pointers captured into UIFIX-04/05/06 for phase 1's gap-closure work — no fixes implemented for these, per scope boundary and explicit direction.
Task Commits
Each task was committed atomically (Task 3's checkpoint follow-up investigation produced additional fix/docs commits, listed under it):
- Task 1: Build and deploy the frontend to the dev pair only -
3ee20430(docs — KEEP_ALIVE_MAX confirmed via on-device memory reading; no code change needed since the constant stayed at 6) - Task 2: Re-measure on archi-dev-box and write the before/after comparison -
f1206ad6(docs — 02-PERF-AFTER.json + FINDINGS.md Results/Outstanding) - Task 3: D-11 pass bar checkpoint - checkpoint:human-verify, first pass returned "otherwise it's getting much better" plus 4 specific issues; investigation and fixes landed as:
e1a3f31a(fix — Cloud.vue fresh-mount guard; necessary, not sufficient alone)834edd8c(docs — checkpoint follow-up: triage of all 5 reported items, root cause instrumentation findings)8fe6217b(fix — content.browse-peer concurrency cap + timeout; the fix that actually closed the regression)a0c58277(docs — confirmation the fix is verified 5/5, mechanism closed)- Final on-node re-check: approved
Plan metadata: (this commit) - docs(02-08): complete dev-pair deploy, on-device re-measure, D-11 pass bar plan
Files Created/Modified
.planning/phases/02-ui-performance/02-PERF-AFTER.json- After-artifact from re-running the 02-01 harness against archi-dev-box (15 rows,commit: "3ee20430",runs: 3).planning/phases/02-ui-performance/02-FINDINGS.md-## Results(per-surface baseline/after comparison + corrected remount verification),## Outstanding(every regression/gap/carried assumption), and a## Addendum: Task 3 Checkpoint Follow-Updocumenting the full investigation and classification of all 5 user-reported itemsneode-ui/src/views/dashboard/keepAliveRoutes.ts-KEEP_ALIVE_MAXcomment updated to record the on-device memory reading that justifies leaving it at 6 (FA-D closed)neode-ui/src/views/Cloud.vue- Fresh-mount guard onsyncOnEntry()(matching Home/Web5/Mesh/Server's existing pattern) +content.browse-peerfan-out capped at 3 concurrent with a 10s per-call timeout (BROWSE_PEER_CONCURRENCY,BROWSE_PEER_TIMEOUT_MS, a queue/worker pool mirroringPeerFiles.vue'sPREVIEW_CONCURRENCYconvention)
Decisions Made
See key-decisions in frontmatter for the full list. Highlights:
- KEEP_ALIVE_MAX stays 6, now backed by a real on-device memory reading rather than the carried-forward FA-D estimate.
- archi-dev-box only —
archy-x250-devwas offline for the plan's entire duration (checked three times); recorded honestly rather than silently skipped, per D-11's specific naming of archi-dev-box as the verification target. - The harness's remount-probe field is unreliable for main tabs post-KeepAlive — corrected via an independent, reproduced-twice verification method rather than editing the frozen 02-01 harness; the correction revealed Server.vue's genuine remount gap, which the raw (confounded) field would have hidden as "unchanged."
- The Cloud first-visit regression was treated as release-blocking, not known-open, per explicit coordinator direction — required isolating the true mechanism (an unbounded, untimed RPC fan-out to dead peers starving the browser's connection pool) rather than stopping at the first plausible-looking fix (the fresh-mount guard alone did not resolve it, and was honestly reported as insufficient before the real fix was found).
- Pre-existing UX issues were classified, not fixed — Paid Files'
window.open()instead of the lightbox, PiP not closing the lightbox, a missing loader state on Paid Files' item-open, and PiP not surviving tab changes/buffering were all traced to commits predating phase 2 (f3393581,f72d4b92, both 2026-07-22/23, confirmed viagit merge-base --is-ancestoragainst thea75b6709pre-phase-2 baseline) — captured into UIFIX-04/05/06 rather than fixed here, respecting this plan's own scope boundary.
Deviations from Plan
Auto-fixed Issues
1. [Rule 1 - Bug, caught by the D-11 checkpoint] Cloud.vue's dual onMounted/onActivated fire doubled the first-activation request burst
- Found during: Task 3 checkpoint, user-reported "first visit to Cloud, no folder opens on click"
- Issue: 02-04 exempted
Cloud.vuefrom the fresh-mount guard pattern used elsewhere (Home/Web5/Mesh/Server), reasoning each individual resource is staleness/inflight-deduped. True per-resource, but the two back-to-backonMounted+onActivatedpasses still doubledloadPeerFiles()'s full per-peer RPC fan-out in the same tick on a component's first KeepAlive activation. - Fix: Added the same fresh-mount guard (
cloudFreshMount) already used in Home.vue/Web5.vue/Mesh.vue/Server.vue. - Files modified:
neode-ui/src/views/Cloud.vue - Verification: Full suite green (95/774); reduced but did not eliminate the reported symptom — honestly reported as insufficient before proceeding to the real fix below.
- Committed in:
e1a3f31a
2. [Rule 1 - Bug, the actual root cause] content.browse-peer's unbounded, untimed-enough fan-out starved the browser's connection pool
- Found during: Task 3 checkpoint follow-up, after fix #1 above did not resolve the reported regression
- Issue: Direct instrumentation (request-lifecycle tracking of every
content.browse-peercall during a fresh Cloud mount) showed 13 of 14 concurrent calls never settling at all —loadPeerFiles()fanned these out with zero concurrency cap and a 30s per-call timeout. That many simultaneously-open, indefinitely-pending same-origin requests to dead/unreachable peers starved Chromium's per-origin connection pool, silently breaking every other same-origin fetch for the rest of the session, including the lazy route chunk any later folder/tab navigation needs. Confirmed not a test-harness artifact (reproduced in full Chromium, not just headless-shell) and not explained by raw concurrency alone (an artificial 30-request burst against the same endpoint, done outside Cloud.vue, completed in 179ms with zero hang). - Fix: Capped the fan-out at 3 concurrent requests (
BROWSE_PEER_CONCURRENCY, a queue/worker pool) and shortened each call's timeout from 30s to 10s (BROWSE_PEER_TIMEOUT_MS), mirroringPeerFiles.vue's existingPREVIEW_CONCURRENCYpattern for the identical class of problem. A timed-out/failed peer already resolved silently (no throw, no toast) viaresources.ts's own error-state path — confirmed unchanged. - Files modified:
neode-ui/src/views/Cloud.vue - Verification: Full suite green (95/774), type-check and build clean,
keepAliveTabs.test.tsstructural assertions untouched. 5/5 fresh browser sessions (brand-new context each run) navigated cleanly on the first folder click against the redeployed build; zero in-flight hung requests after 15s on Cloud (previously exactly one, permanently pending); a previously-permanently-hung lazy route chunk import resolved in 17ms. User's final on-node re-check: approved. - Committed in:
8fe6217b
Total deviations: 2 auto-fixed (both Rule 1 — real bugs found during this plan's own verification checkpoint, not pre-existing issues out of scope, since the phase's own lifecycle changes altered when this fan-out fires and turned a latent unbounded-RPC pattern into a deterministic first-visit navigation breaker).
Impact on plan: Both were necessary corrections directly implicated by this plan's own must-have truths (the D-11 pass bar) and explicit coordinator direction that a deterministic navigation breaker cannot ship as known-open. No scope creep — both fixes stayed within Cloud.vue, the file already central to this checkpoint's investigation.
Issues Encountered
- Authentication gate on Task 1/Task 2: archi-dev-box's real UI password was needed to drive the Playwright harness and was not derivable from this environment (matching 02-01's precedent). Paused at a
checkpoint:human-action; the coordinator supplied the password out-of-band, passed only via theARCHY_PASSWORDenvironment variable at runtime, never written to any committed file. - A recurring auto-show engagement/feature-announcement modal (the same class of overlay 02-01 documented as
CompanionIntroOverlay) intermittently intercepted clicks during on-device testing across this plan's Playwright-driven diagnostics; worked around per-script with a dismiss-if-present check, never touched in application code (out of this plan's scope). - The node's disk usage is genuinely at 85% right now, triggering a persistent
HealthNotifications.vuetoast that intercepted Chat's close button in this run (a different specific blocking cause than baseline's AIUI-connection-timeout reason, same "unmeasured" outcome for Chat). Flagged inFINDINGS.mdas worth a follow-up fix (the toast's wrapper lackspointer-events: none) independent of this phase.
User Setup Required
None — no external service configuration required. archi-dev-box's real UI password, used to drive on-device verification, was supplied out-of-band by the coordinator and passed only via the ARCHY_PASSWORD environment variable at runtime; it is not stored in any file in this repository.
Next Phase Readiness
- PERF-01, PERF-02, and PERF-03 are all now genuinely complete — PERF-03 specifically required real-node-hardware verification per its own requirement text, which this plan's Task 3 checkpoint (including the regression it caught and this plan closed) provides.
- Open, non-blocking follow-ups carried forward (all recorded in
02-FINDINGS.md's## Outstanding, none block this phase's completion per the user's own "otherwise much better" call):- Server.vue does not survive a tab round-trip despite being registered in
KEEP_ALIVE_PATHS— a real, confirmed gap needing a future targeted fix. - Timing regressions on Discover/Web5/Fleet/AppDetails/OpenWrtGateway, recorded honestly with numbers; a same-time-of-day re-run would help disambiguate real regression from environmental (85%-disk, multi-service node) noise.
archy-x250-devhas received none of this phase's changes — needs the same--frontend-onlydeploy once it's back online./dashboard/settingsremains withheld fromKEEP_ALIVE_PATHS(02-04's own deliberate, unaudited-risk exclusion).cloudStore.navigate()'s residual TTL gap (02-03's known gap) andPeerFiles.vue's non-useCachedResourcefetch pattern (02-03's own flagged correction) remain open.- UIFIX-04/05/06 now have exact file/line pointers for four pre-existing UX issues surfaced during this plan's checkpoint, ready for phase 1's gap-closure work.
- Server.vue does not survive a tab round-trip despite being registered in
- No blockers for the milestone's next phase.
Phase: 02-ui-performance Completed: 2026-07-30
Self-Check: PASSED
All claimed files found on disk (02-PERF-AFTER.json, 02-FINDINGS.md, keepAliveRoutes.ts, Cloud.vue) and all claimed commits found in git history (3ee20430, f1206ad6, e1a3f31a, 834edd8c, 8fe6217b, a0c58277).