Reassessed after the OpenWrtGateway override (commit b4350e24) closed the
single open item from the prior human_needed pass. Judged the override on
its merits: well-formed, corroborated by a direct first-person quote from
Dorian this session, with one noted imprecision (the rationale slightly
overstates that no measurement at all is obtainable, when the
disconnected-state UI could technically still be re-measured) that doesn't
change the substance of a legitimate stakeholder scope call. With both
residual, non-poller-fixable costs (Discover's animation replay,
OpenWrtGateway's untestable hardware dependency) now individually accepted
by rationale-backed override, and every other named regression fixed or
substantially recovered, status is passed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No OpenWrt device is connected to this node, so the surface cannot be
exercised and no post-fix measurement is obtainable. The user decided to pass
it for this milestone. Also notes that its earlier baseline/regressed figures
measured a disconnected-device UI rather than the real screen, and records the
residual risk for the next milestone.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Independently re-derived all 02-11/02-12 claims: recomputed every claimed
median directly from 02-PERF-FINAL.json's raw samples (all match), confirmed
the frozen perf harness is still byte-for-byte untouched, re-ran the
keepAliveLifecycle regression suite (19/19) and the full workspace suite
(788/788), and confirmed the three leaked-poller fixes are genuinely wired
in source. Discover's override is well-formed and corroborated across three
independent artifacts. Status: human_needed — OpenWrtGateway is the one
named regression with zero post-fix measurement (crashed for an unrelated
reason) and no override scoped to it; everything else is either verified
fixed, substantially recovered with an honest residual, or formally
overridden by Dorian.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Dorian decided entrance-animation behavior is his domain and is not to be
changed, cancelling this gap-closure plan before any source file shipped.
The composable drafted during investigation was deleted (never imported).
Preserves the investigation findings (blast radius, the ~241ms-1716ms
measured cascade, the first-paint-901ms-of-1095ms evidence, the Apps-revisit
184-267ms calibration, and the pre-phase-2-baseline note) so the analysis
isn't lost or re-done. Discover's revisit cost stands as a formally accepted
deviation at its 02-11 FINAL number.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The re-verification required either a fix or an accountable stakeholder
decision. Plan 02-11 fixed four of five measurable surfaces. 02-12 isolated
Discover's remainder to the card-stagger entrance animation replaying on every
revisit; the only fix changes animation behavior, which Dorian rules off-limits
as his domain. Decision recorded with rationale, evidence and attribution.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
02-11 named a second, distinct cause of Discover's revisit slowness with
full profiling evidence (card-stagger/home-card-animate classes never
removed from the DOM, so Chromium restarts the CSS entrance animation on
every KeepAlive reattach) but deliberately left it unfixed — the blast
radius (Discover/Apps/Marketplace/Home + Web5 sub-cards) exceeded that
plan's scope. This gap plan fixes every affected site with one shared
composable rather than per-file patches, decouples Home.vue's dual-purpose
animateCards ref so its overlay/EasyHome visibility logic stays untouched,
and ends at a blocking human-verify checkpoint before any SUMMARY is written.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The code-fixer correctly declined this change twice on relayed consent. It was
then made by the orchestrator holding first-hand authorization from Dorian, who
chose forced auto-update with the mid-payment reload risk explicitly stated and
rejected warning UI. Records the quote, and that the implementation reused the
existing kiosk auto-apply path (preserving the cinematic and first-install
guards) rather than flipping build-time skipWaiting.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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>
Deployed the poller fix to archi-dev-box and re-ran the frozen harness
(02-PERF-FINAL.json, 5 runs/surface). Web5 fixed (275ms, below both
its 566ms pre-phase-2 baseline and the 300ms pass bar). Server's
regression closed (574ms, below 738ms baseline) though not yet under
300ms. Fleet substantially improved (790ms, down from a 2631ms
regression). AppDetails restored to at/near its own baseline.
Investigated the two open items the coordinator raised:
- OpenWrtGateway: this run's 5/5 samples failed with a Chromium
"Target crashed" error cascading from an unrelated surface earlier
in the same harness run — recorded as not-measurable, not written
in as data. Separately confirmed via source (OpenWrtGateway.vue's
h1 renders unconditionally, and a "No router configured" RPC error
deterministically shows a real Connect-to-Router form) that the
prior baseline/after/remeasure numbers were measuring a genuine,
substantive disconnected-state UI render, not an empty/error page —
so the "six confirmed regressions" count is not retracted, but the
numbers are flagged as reflecting one specific code branch.
- Discover (1389ms, worst remaining, least improved): profiled
directly and found a SECOND, distinct, phase-2-class cause —
showStagger/card-stagger entrance-animation classes are baked into
the DOM at first mount and never programmatically removed (the flag
is a correctly-scoped once-per-session const, but nothing ever
re-renders to strip the class), so every KeepAlive detach/reattach
cycle restarts the CSS animation on reactivation, replaying the full
entrance cascade on every revisit. Confirmed via a diagnostic
showing DOM card count doubling transiently on every revisit and an
extended animationstart/animationend event log. Not fixed this pass
— the safe fix's blast radius spans 5+ files outside this plan's
scope (Apps.vue, Marketplace.vue, Home.vue, several Web5 sub-cards)
and needs its own real-device verification budget, matching the
precedent 02-02's original KeepAlive rollout needed for this exact
class of change. Named and evidenced, recommended as a dedicated
follow-up rather than expanded into this plan under time pressure.
REQUIREMENTS.md's PERF-02/PERF-03 rows updated to the final state.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fleet.vue's useFleetData() (60s telemetry.fleet-status/-alerts poll),
Server.vue's FipsNetworkCard.vue (15s fips.status poll), and Web5.vue's
Web5Monitoring.vue (30s system.stats poll — redundant with Home.vue's
own correctly-gated 10s poll of the same store) all armed their
setInterval in onMounted and only disarmed it in onUnmounted/
onBeforeUnmount. That was harmless before 02-04 registered their
owning views in KEEP_ALIVE_PATHS (the view was destroyed on every
tab-away, so the teardown hook fired every time); once KeepAlive keeps
the instance alive, the teardown hook never fires again and the poll
ran forever in the background regardless of which dashboard tab was
showing.
Gated arm/disarm to onActivated/onDeactivated, mirroring Server.vue's
own vpnPollInterval fix from 02-04 exactly. Added regression tests to
keepAliveLifecycle.test.ts mounting each real component under a
synthetic KeepAlive with fake timers; confirmed RED against the
pre-fix code (git stash) before confirming GREEN with the fix restored.
Full suite (95 files/788 tests), type-check and build all green.
keepAliveTabs.test.ts is byte-for-byte unmodified.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
CPU profile evidence (CDP Profiler + Tracing, additive
neode-ui/e2e/perf/profile-revisit.spec.ts, frozen harness untouched)
shows 86-99% of every revisit window spent in (idle)/(program) with
under 10% genuine app JS self-time on every surface — ruling out
expensive computed re-evaluation, watcher cascades, and whole-subtree
re-renders as the dominant cost, per the plan's own explicit list of
hypotheses to check before accepting one.
A follow-up source-level lifecycle audit (grep every setInterval call
site for a missing onActivated/onDeactivated pair, extending 02-04's
own audit convention past the top-level view files it originally
checked) found three child components/composables inside the
KeepAlive'd Fleet/Server/Web5 subtrees that arm a poll in onMounted
and only ever clear it in onUnmounted — harmless before phase 2
(the view was destroyed on tab-away) and now a permanent, session-long
background-RPC cost once KeepAlive keeps the parent instance alive:
useFleetData.ts (60s), FipsNetworkCard.vue (15s, Server), and
Web5Monitoring.vue (30s, Web5 — redundant with Home.vue's own,
correctly-gated 10s poll of the same store).
This directly explains the idle-dominated CPU signature (background
network/scheduling contention, not compute) and why 02-10's 5-run
remeasure regressed further than the 3-run baseline/after runs even
as disk pressure eased: a longer session accumulates more of these
always-on pollers, degrading every subsequent navigation.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fleet/AppDetails/Web5/OpenWrtGateway/Server/Discover all measured
slower on revisit than the pre-phase-2 baseline (02-10's three-way
dispersion analysis). This plan profiles the real cause per surface
before touching source (D-10), fixes what's fixable without
reverting any T-02-01 persist:false decision or touching the
visual/animation contract, and re-measures with the frozen harness.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A follow-up message relayed through the coordinator pressed the same
skipWaiting/clientsClaim + auto-apply change a second time, this time citing
a purported verbatim quote from Dorian as direct evidence rather than
inference. Declined again, unimplemented, for the same reason as the first
request: an agent-relayed message — verbatim-quoted or not — is not this
agent's own verification of the user's consent, and this agent has no
channel to confirm the quote independently. vite.config.ts and
PWAUpdatePrompt.vue remain unmodified.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- New `## Re-measurement (gap closure)` section in 02-FINDINGS.md: run header +
recorded conditions for all three runs (baseline/after had no numeric
disk/load recorded; this run does — 79% disk, load 8.70-11.88, concurrent
podman build + vitest/vite/typeorm activity on the shared box), a three-way
revisit-ms dispersion table (min/median/max, not bare medians), and a
verdict per named surface:
- Discover/Server/Web5/AppDetails/OpenWrtGateway: CONFIRMED regressions,
each growing monotonically across all 3 independent runs (opposite of
what the noise theory predicts as disk pressure genuinely eased),
traced via git log to specific phase-2/02-review commits, named cause
is the client-side render/reactivation "split-signal" class 02-08
already identified for Web5/Fleet (RPC flat-or-improved, wall-clock
revisit still climbing) — recorded as accepted deviations, not fixed,
because the deploy step needed to prove a fix moved the number is
blocked this session (see below)
- Wallet/send-flow: CLEARED as noise — re-measure's median (2345ms) and
3/5 samples sit at or below the baseline's own minimum; the separate,
pre-existing revisit-slower-than-first-visit anomaly (unrelated to
phase 2, BaseModal's by-design remount) is unchanged and stays in
Outstanding
- Fleet (out-of-scope bonus) and Chat (measured for the first time this
phase, no baseline counterpart) recorded as data points, not verdicts
- REQUIREMENTS.md: PERF-02/PERF-03 traceability rows updated to point at
this section (scope deviation from files_modified, per plan checker note
— the coverage-table update this plan's own Task 2 text calls for)
Deploy note: Task 1 deployed archi-dev-box to 3e3159fa (frontend-only,
clean tree, dirty=false) before measuring, since 4 of 6 named surfaces are
touched by the 02-review commits the previously-deployed 8fe6217b predates.
Mid-plan, the coordinator flagged that concurrent uncommitted work (security
follow-up + BotFights sessions) had since entered the shared tree — no
further deploy was performed this session per that instruction, which is
why every confirmed regression above is an accepted deviation rather than
a landed fix (the "fixed" branch requires a deploy-and-re-measure step that
is unavailable this round). `neode-ui/e2e/perf/02-REVIEW.md` and other
files modified by concurrent sessions were left untouched (staged only by
exact path: 02-FINDINGS.md, REQUIREMENTS.md).
Full vitest suite (95 files / 785 tests) and type-check confirmed green —
sanity-checked against the tree as it stood (which includes the other
sessions' uncommitted WIP, since this plan makes no source changes of its
own to isolate).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Appends a dated addendum to 02-REVIEW.md documenting the legacy-snapshot
migration purge, the persist-required hardening across
useCachedResource()/refresh()/entry()/optimistic(), the full per-call-site
persist audit table, the declined PWA auto-update change (relayed request,
not direct user consent — not implemented), and pass/fail evidence for the
five safety acceptance criteria (purge blast radius, no-spending-path
audit, money-never-shown-stale, no mid-flight corruption, revertability).
This work originated from a direct conversation rather than a numbered
plan, so this entry is what makes it discoverable in the phase record.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Frontend-only deploy to archi-dev-box first (commit 3e3159fa) — last deploy
was 02-08's fix (8fe6217b), predating the 02-review commits that touch
Web5/Discover/Server/OpenWrtGateway and 02-09's investigation; deployed
clean (dirty=false) before any concurrent uncommitted work landed in the tree
- Harness confirmed byte-for-byte frozen: git diff --stat 3ee20430 -- neode-ui/e2e/perf/
shows only the new keepalive-remount-probe.spec.ts (02-09), zero changes to
surfaces.ts/measure.ts/surface-perf.spec.ts
- First attempt (ARCHY_PERF_RUNS=5) hit the harness's own hardcoded 20-min
test.setTimeout under concurrent node load (a botfights podman build +
other sessions), aborting after 9/15 surfaces with the rest failing
"browser has been closed" (not a real measurement, not hand-edited into
the artifact) — re-ran once per the plan's own contingency, completed
clean in 7.9 min once the concurrent build finished
- 15/15 rows recorded; runs: 5, baseUrl: http://archi-dev-box; Mesh unmeasured
again (device not reporting connected, same reason as both prior runs);
Chat measured this time (bonus data point, no baseline-comparable
counterpart — findings doc will say so plainly)
- Conditions recorded: pre-run 06:01 EDT, df 79% (1.4T/1.8T, down from
baseline's 85%), load 8.70/7.99/7.94 with a concurrent podman build
running; post-run 06:42 EDT, df 79%, load 6.88/11.88/9.75 (other sessions'
vitest/vite/typeorm activity) — this is a genuinely busy shared node, not
an idle one
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Task 3 checkpoint approved by user, covering all seven verification items
including the OpenWrt Gateway Connect-form (WR-03) sanity check. Writes
02-09-SUMMARY.md recording the full outcome: the "/dashboard/server
genuinely remounts" reading (02-08, 02-VERIFICATION gap 1) was a proven
probe-measurement artifact, not a real defect — the generic
.view-container [data-controller-container] selector shared by every
KeepAlive-cached main tab couldn't disambiguate the foreground tab from
another still-connected cached tab, confirmed via an authoritative
document.elementFromPoint() hit-test that repeatedly contradicted the
naive "remounted" verdict across independent device runs for both Server
and Web5 (the latter a mid-investigation discovery). The committed
keepalive-remount-probe.spec.ts replaces the ad-hoc 02-08 probe, and four
new vm.$.uid-based regression tests pin real instance survival immune to
the same selector ambiguity.
Updates STATE.md (metrics, decisions, resolved blocker, session) and
ROADMAP.md (02-09 checked off, 9/10 plans executed) for phase 02's gap
closure. No code changes; 02-FINDINGS.md is owned by the concurrently
running 02-10 executor and was not touched here (already committed by
this plan's earlier Task 1/2 commits).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Task 2 (no-op branch, per plan): Task 1's evidence positively proved
Server.vue and Web5.vue's instances already survive tab round-trips —
the "remounts" reading was a probe artifact (02-FINDINGS.md), not a real
defect. No change to DashboardRouterView.vue, dashboardViewWrappers.ts,
keepAliveRoutes.ts or Server.vue's KeepAlive/lifecycle wiring.
Lands 4 regression tests in keepAliveLifecycle.test.ts using Vue's own
component-instance identity (vm.$.uid) instead of a CSS selector, so the
pin can't inherit the same generic-.view-container ambiguity Task 1 found:
round-trip identity for Server (Test 1) and Web5 + a second tab (Test 2),
include-list correctness (Test 3), and the LRU cap staying intact (Test 4).
All four pass immediately against the unmodified code — that pass is
itself the pin, per the plan's explicitly anticipated no-change path.
Full suite green (95 files / 778 tests), type-check clean, build succeeds.
keepAliveTabs.test.ts confirmed byte-for-byte unmodified and still green.
No deploy: nothing in neode-ui/src changed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Task 1: built keepalive-remount-probe.spec.ts, a committed, re-runnable
Playwright spec covering every KEEP_ALIVE_PATHS tab with three added
instruments (instance-uid, session-wide console/pageerror capture, DOM
population/pathname logging per hop) beyond 02-08's ad-hoc probe.
Eliminated suspects 2 (runtime error), 3 (LRU eviction), 4 (route.path
mismatch) and 5 (include-name matching) by direct measurement. Confirmed
suspect 1 with positive proof: an authoritative document.elementFromPoint()
hit-test signal contradicted the naive selector-match method's "remounted"
verdict for both Server and Web5 across independent runs, and a companion
diagnostic found the original stamped root still connected+visible under
a different (unpicked) match. Root cause: Server, Web5 and Fleet share the
fully generic .view-container [data-controller-container] selector every
KeepAlive-cached main tab's root carries via fallthrough, which cannot
disambiguate "the foreground tab" from "another cached tab still connected
to the document" once more than one tab has been visited — the normal,
intended KeepAlive state. Settings (the away tab every round trip uses)
independently renders matching content too (AccountInfoSection/
KioskDisplaySection), compounding the ambiguity.
Server.vue and Web5.vue's instances survive tab round-trips exactly like
every other registered tab — no defect in DashboardRouterView.vue,
dashboardViewWrappers.ts, keepAliveRoutes.ts or Server.vue's KeepAlive
wiring. 02-FINDINGS.md records the full method, eliminated suspects and
verdict per D-10 (this commit lands before any src change, per gate).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Rebasing the review-fix branch onto main (which had advanced with
unrelated 09-06/botfights commits since this branch was created) rewrote
every commit hash. Update 02-REVIEW.md's Status lines and summary table to
reference the post-rebase hashes.
Co-Authored-By: Claude <noreply@anthropic.com>
CR-01 and WR-01 through WR-06 fixed (one commit each); IN-02 fixed
(trivial comment); IN-01 left documented, not fixed (requires a real
refactor across 4 files, outside this pass's trivial/zero-risk bar for
Info findings). Full test suite, vue-tsc --noEmit, and npm run build are
all green after every fix.
Co-Authored-By: Claude <noreply@anthropic.com>
Two plans closing the gaps 02-VERIFICATION.md found (6/8 must-have truths
verified):
- 02-09 (wave 6): Server.vue is registered in KEEP_ALIVE_PATHS since 02-04 but
02-08's corrected, twice-reproduced probe shows it fully remounting on every
revisit. Names the measured cause first (D-10), commits the ad-hoc probe as a
re-runnable spec, lands a targeted fix pinned by a regression test in
keepAliveLifecycle.test.ts, deploys frontend-only to archi-dev-box (D-15),
and closes with the D-11 human pass bar.
- 02-10 (wave 7): the six surfaces measured unimproved/regressed vs baseline had
a flagged-but-untested environmental-noise confound. Re-runs the frozen 02-01
harness under recorded conditions, compares three-way using per-run sample
spread rather than bare medians, and gives every named surface a verdict —
cleared with data, fixed, or an explicit accepted deviation for the verifier.
Co-Authored-By: Claude <noreply@anthropic.com>
Updates the Task 3 checkpoint follow-up addendum: the content.browse-peer
concurrency-cap fix (8fe6217b) resolved what the fresh-mount guard
(e1a3f31a) alone did not. Instrumentation showed 13 of 14 concurrent
browse-peer calls never settling; capping the fan-out at 3 concurrent
with a 10s per-call timeout eliminated the hang. Verified 5/5 fresh
sessions navigate cleanly on first folder click against the redeployed
build, zero in-flight requests after 15s on Cloud, and a previously-
hung route chunk import now resolves in 17ms.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds a Task 3 checkpoint follow-up addendum to FINDINGS.md documenting
the investigation behind the fix(02-08) commit (Cloud.vue fresh-mount
guard for the first-visit connection-pool stall — confirmed real,
partially fixed, not yet fully resolved) plus classification of four
other user-reported items, all traced via git history against the
a75b6709 pre-phase-2 baseline and confirmed pre-existing (not phase 2):
Paid Files opening images in a new tab instead of the lightbox, PiP not
closing the lightbox, missing loader state on Paid Files' item-open RPC,
and PiP not surviving tab changes/buffering pauses. No fixes applied
for the pre-existing items per standing direction (captured separately
as phase-1 UX work).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Re-ran the plan 02-01 harness unmodified against archi-dev-box (same
target, same runs:3 contract) producing 02-PERF-AFTER.json (15/15 rows,
matching the baseline row count). Appended FINDINGS.md's Results table
(per-surface baseline/after comparison, Verdict) and an Outstanding
list of every regression, unmeasured surface, and unsettled gap.
Discovered and cross-verified (via a corrected, harness-independent
remount probe, reproduced twice) that the harness's own remount-probe
selector ('.view-container', generic and shared across every main tab)
became ambiguous once real KeepAlive caching keeps multiple instances
alive simultaneously — the raw artifact's 'remounted' field is
confounded for main tabs whose instance actually survives. Corrected
readings show Home/Apps/Marketplace/Cloud/Web5/Fleet genuinely survive
a round-trip; Server genuinely does not (a real, confirmed gap against
this phase's own must-have truth, flagged in Outstanding, not fixed
here — out of this task's measurement-only scope).
Also recorded real timing regressions (Discover, Server, Web5, Fleet,
AppDetails, OpenWrtGateway) honestly rather than averaging them away,
per the plan's own prohibition, alongside a timing-variance caveat
(baseline and after-run were taken at different times of day on the
same multi-service node).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
AIUI is now cloned at /home/archipelago/Projects/AIUI
(git.tx1138.com/lfg2025/AIUI, development branch — 17 commits ahead
of main with zero unique main commits). Replaces the exhausted-search
conclusion with the real embed-parameter contract read from source
and records the D-14a/D-14b implementation: chatCollapsed's initial
state now honors a new ?chatExpanded param (chat.ts), and ChatPage.vue
re-asserts mobileTab='chat' on mount when ?mobileChat is present,
guarding against carry-over from AIUI's own module-singleton content-
panel state on an internal remount. Both are static, unconditional
query params — no runtime-varying URL input.
AIUI-side commit lives on feat/d14-embed-defaults (900c0b9) in the
local clone only — anonymous push to origin returned 403 Forbidden.
Needs a maintainer with push rights to land it before any deployed
AIUI build can honor these two parameters.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Task 1 of plan 02-07. Searched the expected sibling AIUI/ checkout
(both relative-path forms neode-ui/package.json and
scripts/setup-aiui-server.sh reference), a broader filesystem sweep
for any directory named AIUI holding source rather than a prebuilt
dist/, and the ThinkPad build server (.116) noted in project memory
— all three came up empty (no sibling checkout, no other source dir,
.116 unreachable via ping/ssh right now).
Recorded the existing embed-parameter contract from Chat.vue plus
diligence findings from the currently-deployed AIUI build's static
bundle (embedded/mockArchy/hideClose support), and marked both D-14
defaults as needing a new AIUI-side parameter or postMessage control
that cannot be added without source access. Deployment impact section
covers the prebuilt-image rebuild path per apps/aiui/manifest.yml and
D-15's dev-pair-only constraint.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every claim cites 02-PERF-BASELINE.json (archi-dev-box, real hardware).
13/15 surfaces measured cleanly; Mesh and Chat recorded as unmeasured with
reasons, never as already-fast.
Key findings:
- 4 main tabs (Home, Apps, Cloud, Fleet) measure already fast — left alone
per D-02, KeepAlive wrapping only, no data-cache conversion.
- Marketplace is the worst main tab (2033ms revisit) and the tracer pick
for 02-02, matching the user's own complaint ("often app store").
- No surface shows a serial-RPC-waterfall signature (maxConcurrentRpc is
at or near each surface's total call count everywhere multiple calls
were observed) — corrects RESEARCH.md's one "confirmed" waterfall
target, ContainerAppDetails.vue, which this session's grep confirms is
fully unreachable dead code (no importer, no route entry). D-13's
parallelization pattern has no live target in this phase's D-09 set.
- Flagged a measurement confound: 3 rows (Marketplace, MarketplaceApp-
Details, OpenWrtGateway) reach their target via a navSteps chain that
transits another main tab first, so some of their captured RPC calls are
that intermediate tab's own onMounted burst, not the destination's.
Classified conservatively (remount storm, not uncached fetch) with the
confound spelled out for 02-02/02-03 to re-verify before assuming.
- Wallet-send's revisit (2607ms) is consistently slower than its first
visit (735ms) across all 3 runs despite zero RPC either time — flagged
as an anomaly for 02-03 to profile directly, not hidden.
This is the last commit in this plan — the gate 02-02 through 02-08 depend
on before any neode-ui/src change lands (git diff --name-only HEAD~2..HEAD
-- neode-ui/src is empty across all three of this plan's commits).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 02-PERF-BASELINE.json: on-device baseline recorded against archi-dev-box
(real hardware, D-11's verification target). 13/15 surfaces measured
cleanly across 3 runs each; Mesh and Chat are recorded as unmeasured with
their reasons (Mesh: no connected mesh device on this node within the
wait window; Chat: AIUI's own loading overlay outlives the close-button
click budget) rather than silently marked already-fast, per plan rule.
- measure.ts: goHome() now falls back to a hard `page.goto('/dashboard')`
when the Chat surface's own close button is unreachable (blocked behind
AIUI's connecting overlay on real hardware) — without this, every
surface after Chat inherited a permanently hidden sidebar
(`v-show="!chatFullscreen"`) and cascaded to unmeasured. This recovery
path is exempted from the "no page.goto between surfaces" rule because
it exists only to break out of a stuck state, not to measure one.
- surface-perf.spec.ts: currentCommit() now shells out with `process.cwd()`
instead of `__dirname`, which is unavailable under this package's
`"type": "module"` runtime and was silently recording every run header's
`commit` field as 'unknown'.
No file under neode-ui/src/ was modified by this task (git diff --name-only
HEAD -- neode-ui/src is empty).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codebase-grounded research for KeepAlive/SWR caching, serial-waterfall fixes,
and the AIUI D-14 ride-along dependency risk.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>