⌂ Home ☷ Board

PKA Command Centre — Deep Review (2026-06-12)

Scope: dashboard.py (generator, 4,864 lines), serve_dashboard.py (Flask server, 2,873 lines), the generated dashboard.html (~2.5MB), and the LIVE app at http://localhost:8787 — tested in a real browser (all 6 tabs, screenshots in .scratch/wf-review/ux/).

Method: ultracode multi-agent workflow (run wf_ab1d9721-e04, 79 agents): 6 dimension finders (generator correctness, server correctness, data accuracy, dead/duplicated code, performance, live-browser UX) → every finding independently reproduced by an adversarial verifier → second independent verifier for high-severity items. 62 findings confirmed, 4 refuted. Read-only review; nothing fixed.

Headline: the command centre has one architectural keystone problem (viewing the page triggers the full data pipeline, and the page re-downloads itself every 30s) and a cluster of silently-wrong numbers on the Home tab (session counts contradict themselves three ways; the activity feed shows March as 'recent'). Several health cards show green for things that are actually broken — the exact failure the dashboard exists to catch.


Findings (priority order)

Severity: HIGH

1. Session counting: page shows three contradictory numbers (baked 106/43-active war strip vs live API 0), driven by get_sessions counting every transcript .jsonl — claude-mem observer files flood it

2. KYC unverified-fields card scans a non-existent path and always renders a green 'All KYC fields verified' all-clear

3. Home 'Open Sessions' is overwritten to 0 on page load — live API reads an empty registry while dozens of sessions are active

4. Activity feed and 'Usage by Role' recents sort by id DESC, but activity_log ids are not chronological — today's events buried at position 1,787, 'recent' shows 31 March

5. Live WS refresh silently wipes in-progress user input every ~10-15s (filter text, checkbox selections)

6. War-strip session ticker accumulates duplicate cards without bound (60 → 136 in ~30 min, 20,000px wide)

7. Home claims '0 sessions / 0 active' while the war-strip directly above shows dozens of live session cards

Severity: MEDIUM

8. Three weekly wiki-compile targets (safair-holdings, safair-operations, safair-lease-finance) have never been produced — pages CLAUDE.md cites as readable don't exist

9. get_active_agents queries a table (agent_events) that does not exist in vault.db; the exception is swallowed, so org-chart live-agent status is permanently dead

10. Baked session count is inflated by claude-mem observer transcripts and swings wildly (34→126→148 in 35 min)

11. Dashboards listing and serving use two diverged path resolvers — newest Exco Dashboard (9 June) is served but invisible in the command centre

12. Open dashboard tab drives a full server regeneration pipeline every 30s, continuously

13. GET /dashboard.html synchronously runs index.py + generate_context.py + full rebuild in the request path, with no staleness check

14. Raw Node.js stack trace dumped into the Home tab QMD card (QMD integration broken)

15. MEMORY.md overflow health check measures the wrong metric (200 lines) on the wrong file — the actually-overflowing auto-memory index (38.4KB > 24.4KB, truncated at load) is invisible and the card shows green

16. Generator-emitted 30s polling loop forces a full dashboard.py regeneration (index.py reindex + qmd subprocess + transcript scan) for every open tab

17. Memory tab '378 integrity issue(s)' banner: all 305 'index drift' rows are reports intentionally migrated to cloud PKA-Outputs — files exist and serve fine

18. Spend tile shows '$35,687.48' lifetime estimated cost with no 'estimated' label or time period, and token total silently omits 647M cache-creation tokens

19. Activity log rendered with no LIMIT: 3,392 rows = 1.54MB = 62% of the entire page

20. Page views cause vault.db writes: index.py (a DB writer) runs every 30s as a side effect of GET

21. doRefresh refetches the whole 2.49MB page and innerHTML-swaps ~36,700 elements when a 1ms JSON endpoint already exists

22. Entire activity history baked into the DOM: 3,456 timeline nodes / 321,485px of content inside a 520px scroll box

Severity: LOW

23. War-strip cards render the raw encoded project dirname as 'persona' (e.g. '-Users-elmar--claude-mem-observer-sessions')

24. Agent-dispatch 'this week' window is 8 days inclusive, not 7

25. Non-integer query params crash to HTTP 500 instead of 400 (multiple endpoints)

26. System tab 'Skill Audit dashboard' link points to /skill-audit which 404s — route does not exist

27. Reports tab lists 25 node_modules README/CHANGELOG/license files as reports (~5% of the 489 cards)

28. Placeholder-dated stub reports ('…-2099-01-01') from scheduled tasks shown as fresh 2026-06-09 reports