16 KiB
Raw Blame History

phase, slug, status, nyquist_compliant, wave_0_complete, created
phase slug status nyquist_compliant wave_0_complete created
2 ui-performance draft false false 2026-07-30

Phase 2 — Validation Strategy

Per-phase validation contract for feedback sampling during execution. Backfilled from the 8 plans' actual <verify><automated> blocks (02-01 … 02-08).


Test Infrastructure

Property Value
Framework Vitest 3.1.1 (jsdom, globals) + @vue/test-utils; Playwright 1.58.2 for the perf harness only
Config file neode-ui/vitest.config.ts (present); neode-ui/playwright.config.ts (present, ARCHY_BASE_URL override)
Quick run command cd neode-ui && npm run test -- <path/to/file>.test.ts
Full suite command cd neode-ui && npm run test (vitest run)
Type gate cd neode-ui && npm run type-check (vue-tsc --noEmit) — chained into every plan's verify
Build gate cd neode-ui && npm run build (vue-tsc -b && vite buildweb/dist/neode-ui/) — chained into the last task of plans 02-04/05/06/07 and 02-08 Task 1
Estimated runtime Single file ~5s · full suite ~57s (measured 2026-07-30: 84 files / 700 tests, all green) · type-check ~1s · build is the long pole

All infrastructure is already installed — no framework install is required by this phase.


Sampling Rate

  • After every task commit: the task's own <automated> command — a targeted npm run test -- <touched test file> plus npm run type-check (~5-10s).
  • After every plan wave: cd neode-ui && npm run test (full suite, ~57s). Every plan's final task already chains the full suite, so wave completion implies a green full run.
  • Before /gsd-verify-work: full suite green and 02-FINDINGS.md ## Results committed and the D-11 manual pass-bar walkthrough on archi-dev-box (02-08 Task 3).
  • Max feedback latency: < 60s for any test-only verification; build-inclusive tasks (02-04-02, 02-05-02, 02-06-02, 02-07-02, 02-08-01) are longer by one production build.

Per-Task Verification Map

Task ID Plan Wave Requirement Threat Ref Secure Behavior Test Type Automated Command File Exists Status
02-01-01 01 1 PERF-01 T-02-06, T-02-08 Harness records RPC method names + timings only — no request/response bodies, page text or screenshots e2e (Playwright) + tsc cd neode-ui && npx tsc --noEmit -p tsconfig.json 2>&1 | grep -v 'e2e/test-results' ; npx playwright test e2e/perf/surface-perf.spec.ts --project=chromium --reporter=line created in-task pending
02-01-02 01 1 PERF-01 T-02-06 Baseline artifact carries timings and method names only artifact assertion node -e "const r=require('.../02-PERF-BASELINE.json'); const rows=r.results??r; if(!Array.isArray(rows)||rows.length===0)process.exit(1); const bad=rows.filter(x=>x.error==null&&(x.revisitMs==null||x.revisitRpcCount==null)); if(bad.length){console.error('incomplete rows',bad.map(b=>b.id));process.exit(1)} console.log('rows',rows.length)" artifact created in-task pending
02-01-03 01 1 PERF-01 T-02-06, T-02-07 Redaction pass before commit — onion addresses, DIDs, pubkeys, wallet figures, peer hostnames, file names doc-structure assertion test -f .../02-FINDINGS.md && for s in '## Method' '## Per-Surface Findings' '## Ranked Fix Order' '## Surfaces Left Alone' '## Corrections to Prior Research' '## Owning Plans'; do grep -qF "$s" .../02-FINDINGS.md || { echo "missing: $s"; exit 1; }; done; echo OK doc created in-task pending
02-02-01 02 2 PERF-02 T-02-01, T-02-02, T-02-09 Explicit per-resource persist decision (not the default); no identity-bearing cache key before 02-03 lands unit (Vitest + @vue/test-utils) cd neode-ui && npm run test -- src/views/dashboard/__tests__/keepAliveTabs.test.ts src/composables/__tests__/useCachedResource.test.ts && npm run type-check both created in-task (TDD RED) pending
02-02-02 02 2 PERF-02 T-02-03 Intervals/subscriptions stop on onDeactivated; KEEP_ALIVE_MAX = 6 with LRU eviction unit + full suite cd neode-ui && npm run test -- src/views/dashboard/__tests__/keepAliveTabs.test.ts && npm run type-check && npm run test (from 02-02-01) pending
02-02-03 02 2 PERF-02 N/A manual (checkpoint:human-verify, blocking) N/A — see Manual-Only Verifications pending
02-03-01 03 2 PERF-03 T-02-02 resources.clearAll() called from auth.logout() on success and failure paths; purges the resource: sessionStorage prefix unit cd neode-ui && npm run test -- src/stores/__tests__/resourcesClear.test.ts && npm run type-check created in-task pending
02-03-02 03 2 PERF-03 T-02-01, T-02-11, T-02-12 Every key embeds the route item id (isolation asserted on rendered content); credentials/DIDs/wallet are persist: false; invalidate() on destructive-action completion unit cd neode-ui && npm run test -- src/views/__tests__/secondaryScreenCache.test.ts && npm run type-check created in-task pending
02-03-03 03 2 PERF-03 T-02-10, T-02-12 File listings and media metadata are persist: false unconditionally, independent of findings classification unit + full suite cd neode-ui && npm run test -- src/views/__tests__/secondaryScreenCache.test.ts && npm run test && npm run type-check (from 02-03-02) pending
02-04-01 04 3 PERF-02 T-02-03, T-02-13, T-02-15 Timers/subscriptions/listeners follow activation not mount; starts are idempotent (no double-arm); live-data surfaces revalidate immediately on onActivated unit + full suite cd neode-ui && npm run test -- src/views/dashboard/__tests__/keepAliveLifecycle.test.ts && npm run test && npm run type-check created in-task pending
02-04-02 04 3 PERF-02 T-02-14 Exact-path matching retained; shouldKeepAlive asserted false for six secondary-screen paths whose prefixes match a registered tab unit + full suite + build cd neode-ui && npm run test -- src/views/dashboard/__tests__/keepAliveLifecycle.test.ts src/views/dashboard/__tests__/keepAliveTabs.test.ts && npm run test && npm run type-check && npm run build (from 02-04-01, 02-02-01) pending
02-04-03 04 3 PERF-02 T-02-03 N/A manual (checkpoint:human-verify, blocking) N/A — see Manual-Only Verifications pending
02-05-01 05 4 PERF-02 T-02-01, T-02-13, T-02-16 persist: false on every group carrying a DID, onion address, pubkey or contact record; no per-group awaiting (overlapping start times asserted) unit + full suite cd neode-ui && npm run test -- src/views/__tests__/meshTabCache.test.ts && npm run test && npm run type-check created in-task pending
02-05-02 05 4 PERF-02 T-02-03 D3 simulation stopped and animation frames cancelled on deactivate; exactly one simulation and one map per session unit + full suite + build cd neode-ui && npm run test -- src/views/__tests__/meshTabCache.test.ts && npm run test && npm run type-check && npm run build (from 02-05-01) pending
02-06-01 06 4 PERF-02 T-02-17, T-02-16 RESEARCH assumption A3 settled per loader with the verdict recorded; any genuine ordering dependency kept ordered; no serialization of the fan-out unit (+ existing regression) + full suite cd neode-ui && npm run test -- src/views/__tests__/serverTabCache.test.ts src/views/__tests__/ServerNetworkRefresh.test.ts && npm run test && npm run type-check serverTabCache created in-task · ServerNetworkRefresh exists pending
02-06-02 06 4 PERF-02 T-02-01, T-02-13, T-02-16 Wallet balances, transaction history, VPN peer identity and Tor onion addresses are persist: false (test-asserted); wallet revalidates unconditionally on re-entry unit + full suite + build cd neode-ui && npm run test -- src/views/__tests__/homeTabCache.test.ts && npm run test && npm run type-check && npm run build created in-task pending
02-07-01 07 4 PERF-02 (D-14) T-02-19, T-02-20 The contract doc is the review point — no identity- or session-bearing parameter may ship in the iframe query string; deployment impact recorded under D-15 doc-structure assertion D=.../02-AIUI-D14.md; test -f "$D" || exit 1; for s in '## Source Location' '## Embed Parameter Contract' '## D-14a' '## D-14b' '## Deployment Impact'; do grep -qF "$s" "$D" || { echo "missing: $s"; exit 1; }; done; echo OK doc created in-task pending
02-07-02 07 4 PERF-02 (D-14) T-02-05, T-02-18 onAiuiMessage origin check untouched — test asserts a foreign-origin message does not set aiuiConnected; flags are presentation-only, no capability/token parameter added unit + full suite + build cd neode-ui && npm run test -- src/views/__tests__/chatAiuiEmbed.test.ts && npm run test && npm run type-check && npm run build created in-task pending
02-07-03 07 4 PERF-02 (D-14) N/A manual (checkpoint:human-verify, blocking) N/A — see Manual-Only Verifications pending
02-08-01 08 5 PERF-01, PERF-02, PERF-03 T-02-21, T-02-22, T-02-03 --frontend-only at the dev pair only; --tailscale/--tailscale-node/OTA forbidden; built bundle greped for a string from every plan before deploy (CLAUDE.md silent-no-op rule) build + bundle grep cd neode-ui && npm run type-check && npm run test && npm run build && for s in shouldKeepAlive RefreshIndicator app-catalog; do grep -rqs "$s" ../web/dist/neode-ui/ || { echo "MISSING FROM BUNDLE: $s"; exit 1; }; done; echo BUNDLE_OK (no new test file) pending
02-08-02 08 5 PERF-01 T-02-06, T-02-22 Same redaction rule as 02-01 — method names and timings only, no addresses, identities, balances or file names; precondition re-greps the asset actually served by the node artifact comparison + doc assertion node -e "const p='.../'; const a=require(p+'02-PERF-AFTER.json'), b=require(p+'02-PERF-BASELINE.json'); const ar=a.results??a, br=b.results??b; if(!Array.isArray(ar)||ar.length!==br.length){console.error('row count mismatch',ar.length,br.length);process.exit(1)} console.log('rows',ar.length)" && grep -qF '## Results' .../02-FINDINGS.md && grep -qF '## Outstanding' .../02-FINDINGS.md && echo OK artifact created in-task pending
02-08-03 08 5 PERF-01, PERF-02, PERF-03 T-02-03 N/A manual (checkpoint:human-verify, blocking — D-11 pass bar) N/A — see Manual-Only Verifications pending

Status: pending · green · red · ⚠️ flaky

Paths abbreviated as .../ are .planning/phases/02-ui-performance/; the plans carry absolute paths. \| in a command cell is a literal |.

Sampling continuity: the four blocking human checkpoints (02-02-03, 02-04-03, 02-07-03, 02-08-03) are each the last task of their plan and are separated by automated tasks — no three consecutive tasks lack an automated verify.


Wave 0 Requirements

No separate Wave 0 plan is needed. Vitest 3.1.1 and Playwright 1.58.2 are already installed and configured, and every missing test file is created inside its own task's TDD RED step rather than deferred — so no task carries a MISSING — placeholder.

Test/harness files this phase creates (owner task in parentheses):

  • neode-ui/e2e/perf/surfaces.ts, e2e/perf/measure.ts, e2e/perf/surface-perf.spec.ts — perf harness (02-01-01)
  • neode-ui/src/composables/__tests__/useCachedResource.test.tsonActivated revalidation + no-op outside <KeepAlive> (02-02-01)
  • neode-ui/src/views/dashboard/__tests__/keepAliveTabs.test.ts — instance identity across a tab round-trip (02-02-01)
  • neode-ui/src/stores/__tests__/resourcesClear.test.ts — cache purge on logout (02-03-01)
  • neode-ui/src/views/__tests__/secondaryScreenCache.test.ts — per-item keying, isolation, invalidation (02-03-02)
  • neode-ui/src/views/dashboard/__tests__/keepAliveLifecycle.test.ts — activate/deactivate timers and path matching (02-04-01)
  • neode-ui/src/views/__tests__/meshTabCache.test.ts — six-group caching without serialization (02-05-01)
  • neode-ui/src/views/__tests__/serverTabCache.test.ts — seven Server load groups (02-06-01)
  • neode-ui/src/views/__tests__/homeTabCache.test.ts — Home caching + wallet freshness (02-06-02)
  • neode-ui/src/views/__tests__/chatAiuiEmbed.test.ts — stable embed URL + origin check intact (02-07-02)

Existing files reused as regression gates: neode-ui/src/views/__tests__/ServerNetworkRefresh.test.ts, neode-ui/src/stores/__tests__/resources.test.ts.

Doc/data artifacts gating downstream waves (deliverables, not tests): 02-PERF-BASELINE.json and 02-FINDINGS.md (02-01), 02-AIUI-D14.md (02-07-01), 02-PERF-AFTER.json (02-08-02).


Manual-Only Verifications

Behavior Requirement Why Manual Test Instructions
Tracer tab feels instant on revisit; subtle refresh indicator appears after TTL; secondary screens still remount; tab transition animation unchanged; offline keeps last value with no toast PERF-02 Perceptual — "no spinner, no blank frame, no animation replay" is a render-timing judgment no jsdom assertion reproduces 02-02 Task 3 <how-to-verify> steps 17 (./scripts/dev-start.sh, :8100 preview against archi-dev)
All ten main tabs instant on revisit with in-page state preserved; Home wallet re-checks on re-entry; Chat panel does not reload; LRU eviction observable at the cap; no off-screen CPU drain PERF-02 Perceptual plus an idle-CPU/fan observation over several minutes — off-screen timer leakage has no deterministic unit assertion 02-04 Task 3 <how-to-verify> steps 19
AIUI panel persists across tab switches and survives a breakpoint resize; chat opens expanded (D-14a); mobile opens on the chat view (D-14b); the AIUI connection still works PERF-02 (D-14) Requires a real mobile viewport and a live AIUI connection across an iframe boundary 02-07 Task 3 <how-to-verify> steps 18
D-11 pass bar — no visible spinner or blank screen on any revisited tab or secondary screen on archi-dev-box; app store immediate after first visit; Mesh graph held; sustained under extended use PERF-01, PERF-02, PERF-03 The phase's own acceptance bar is an explicit on-device subjective judgment on real hardware ("is the sluggishness gone"), not a threshold 02-08 Task 3 <how-to-verify> steps 110, run on the node itself against the deployed build
PERF-01 findings quality — each named cause is actually justified by the cited baseline field PERF-01 02-01-03 automates the doc's structure; the judgment that each cause↔evidence pairing is sound is human review Read 02-FINDINGS.md ## Per-Surface Findings against 02-PERF-BASELINE.json; confirm every non-unmeasured row cites its justifying field

Validation Sign-Off

  • All tasks have <automated> verify or Wave 0 dependencies
  • Sampling continuity: no 3 consecutive tasks without automated verify
  • Wave 0 covers all MISSING references
  • No watch-mode flags
  • Feedback latency < 60s
  • nyquist_compliant: true set in frontmatter

Approval: pending