Files
waggle-os/docs/ux-refactor/p2-verification-record.md
Oleg Maslov 0c3e2ead3b
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled
moving
2026-09-02 10:10:29 +02:00

8.7 KiB
Raw Blame History

P2 — Verification Record: Home Cockpit + Workspace Desktop vs Brief v2.1 (2026-06-11)

Phase: P2 per the ratified sequence (decision register, deltas/open-questions.md) — "verify + J08 alert". Scope verified: PRD §12.1 (Home Cockpit) + §12.2 (Workspace Desktop) functional requirements, states, and acceptance criteria, against main @ 4e3d65d (post-P1a conversion, post-P1b auth gate). Method: 4-lane verification workflow (Home FRs / Home states+AC / Desktop FRs / Desktop states+AC), every claimed gap adversarially refuted by an independent agent; 2 scout lanes (J08 implementation map, wizard onFinish live-run map). 20 agents. Then a 4-lens adversarial diff review (16 agents) over the fixes.

Verdict

25 of 37 verified items met or ratified-divergence; 12 confirmed gaps (1 HIGH, 5 MEDIUM, 6 LOW); 2 gap claims refuted (first-run empty state and AC-k reachability are MET). The HIGH and all tiny/small verified defects were fixed in this phase; feature-shaped gaps are ledgered below.

Fixed in P2 (this phase)

# Sev Item Fix
G8 HIGH "Artifact ready" state dead — getWorkspaceFiles returned the {files:[...]} envelope; normalizeArtifacts silently rendered Artifacts empty forever Envelope unwrap at the fetch layer (adapter.ts) + fetch-layer regression lock (adapter.files.test.ts) — component tests mock the adapter and were structurally blind here
G0 MED Greeting never showed the user's name (B8 backend half landed, FE never consumed userName); raw ISO date rendered verbatim personalizeGreeting() server-side (name spliced into the first clause); formatBriefingDate() in HomeCockpit
G4 MED J08 alert absent (D6 verification item — Journey 6 step 1) needsReviewCount on GET /api/home/briefing (personal-mind, 200-frame bound matching the Memory Center's own window) + attention banner with Review CTA + deep-link chain (below)
G1 LOW Ranking recency-only; PRD says "recency AND priority" applyPriorityRanking() — bounded boost: each pending/blocked item buys up to 5×1h of effective recency
G10 LOW Header type/status hollow — context route never projected them /api/workspaces/:id/context now projects description/type/status (FE already rendered all three)
G11 LOW Stale workspace URL claimed "server offline"; errored screen sticky Duck-typed AdapterHttpError branching: 404 → "Workspace not found" + go-Home CTA, 403 → permission; Retry button + useRevalidateOnError (armed for the transient offline state only)

J08 deep-link chain (new): Home banner → waggle:open-app {appId:'memory', filter:'unreviewed'} → AppShell shim (stash + /memory?filter=unreviewed) → MemoryRoute re-stash on cold load (AutomationsRoute pattern, so typed/refreshed URLs work) → MemoryCenterTab consumes (stash + live event), validates against STATUS_FILTERS, seeds the status filter. Count and view share the same bound (200) and the same mind (personal), so the number always matches what the user lands on.

Diff review (4 lenses, adversarial): 9 confirmed findings (0 critical/high; 2 medium — both test gaps), 3 refuted. All 9 fixed pre-commit: MemoryRoute URL re-stash, revalidation gated to offline-only, monotonic request guard in MemoryCenterTab.load() (also cures the pre-existing rapid-filter race), _phase1-contract.md §2 amendment, queryString filter pin, route-level ranking inject pin, focus-revalidation pin, needs-review comparison query corrected to limit=200.

Met (verified with file:line evidence — highlights)

  • Home: workspaces ranked w/ one-click Continue (real data, personal-only per A2), overnight summary (memories/artifacts/automations/failures), suggested next actions, quick capture (all 4 kinds wired to /api/quick-capture), Ctrl+K hint (D9 "Win+K" pill is gone), loading/first-run/normal/offline/ overnight-failure states, P1b error+retry path (cold-load crash guard survived conversion).
  • Desktop: all 8 PRD tabs present + URL-driven (founder two-seam edit), chat-as-one-widget (D1-4) with ChatHost keep-alive, 5/6 canvas widgets on real feeds, right panel, fixed layout, agents-running indicator, no-memory/active/agent-running/permission/offline states.
  • Refuted as gaps (i.e. actually met): Home first-run empty (Journey 2), Desktop AC-k reachability (memory/artifacts/agents/skills/tasks/automations/settings all reachable from the workspace).
  • Ratified divergences (PRD ≠ code is correct): D5 team/share tier-hidden; configurable widgets later-phase.

Residuals — ledgered, NOT fixed in P2

Item Sev Size Owner
S02-FR2: Memory/Timeline/Settings/Research tabs are placeholders (capability is 1 click away via left-nav routes) MED M P3 (D2) for the Memory tab embed; rest P7
S02-FR5: status bar — automations-active + MCPs-connected chips unbuilt (feeds exist) MED S P7
S01-R4: upNext only carries cron schedules; awareness 'task' rows never aggregated; 'event' has no calendar substrate (defensible deferral) MED S P7 (tasks); register note (events)
S01-R7: activeModels never populated server-side; FE tile inert LOW S P7
S01-R2 aggravator: priority data only computed for the recency top-8 (MAX_RANKED_WORKSPACES fan-out cap) — a high-pending workspace outside the top-8 can't surface LOW S P7
S02-FR3: research-overview widget unbuilt (Research feature wholesale later-phase) LOW S P7 / register note
S02-state-f: sync conflict N/A until team sync (Phase 5 founder-deferred) — record in the D15 state grid LOW doc P7 (D15)
S02-AC-j residue: status can never be non-active (update route doesn't accept status/type) LOW S P7
J08 count bound: getRecent(200) scan undercounts past 200 unreviewed frames (consistent with the Memory Center view itself; large E-11 imports could exceed it — SQL count if exactness ever matters) LOW S P7
AppShell shim filter passthrough has no mounted-router test (queryString + route-level stash are pinned) LOW S P7

Acceptance check 8 — wizard onFinish seeding (LIVE-RUN, first ever)

Result: PASS — after fixing two real defects the run itself surfaced. Driven via Playwright against a fresh sidecar (3333) + Vite dev (8080) with ?forceWizard=true, three full wizard runs.

Defect 1 (state): loadState() re-evaluated the ?forceWizard reset on every call — including the waggle:onboarding-sync reload fired by every wizard save. The moment workspace-create persisted {workspaceId}, the sync reload reset onboarding to {completed:false, step:0} and wiped it; onFinish then ran with a fallback local-* id and the seeding chain silently broke (run 1 ended force-completed by the returning-user auto-complete, user stranded on /home). Fix: once-per-page-load latch (forceWizardConsumed), pinned by p2-onboarding-forcewizard.test.ts.

Defect 2 (navigation): the wizard finishes at pathname /; completing onboarding (normal-priority state) commits before handleOnboardingFinish's navigate (a v7_startTransition update), so the shell mounts at /, IndexRedirect fires, and its /home navigation queues after the wizard's and wins. Fix: one-shot pendingWizardLanding handoff — IndexRedirect honors the wizard's landing target. Live-verified; not unit-pinned (module-internal handoff — the live smoke is the evidence; ledgered).

Run 3 (post-fix) assertions, all green: lands on /workspaces/p2-smoke-three/chat (real server id, not local-*); widget header P2 Smoke Three · general-purpose (wizard persona active); composer prefilled Hello! What can you help me with? (QW-1 starter, NOT sent); waggle-chat-state-v1 persisted the persona; zero chat-completion/LLM requests in the network log. Smoke workspaces deleted after.

Flagged for founder (production-class, NOT fixed here): the returning-user auto-complete (useOnboarding.ts "Bug #2" effect) completes the wizard whenever a useOnboarding instance mounts with completed:false, no forceWizard in the URL, and ≥1 workspace on the server. Its own comment says the boot-time wsManager.ensureDefault stub counts. If ensureDefault seeds default-workspace before first FE mount on a clean install, a truly-new production user may never see onboarding at all (and the Tauri filesystem first-launch flag does not gate this effect). Needs a clean-install verification (P4/D12 binary work is the natural place); until then this is a suspected launch-integrity defect, not a confirmed one.

Gates at close

FE tsc 0 · server tsc 0 (after npm run build:packages) · FE vitest 75 files green · server-local green · npm run lint exit 0. Suite counts in the session handoff.