Skip to content

fix(dashboard): remove fabricated stats, activity feed, and gold widget#164

Merged
operatoruplift merged 1 commit intomasterfrom
dashboard-honesty
Apr 27, 2026
Merged

fix(dashboard): remove fabricated stats, activity feed, and gold widget#164
operatoruplift merged 1 commit intomasterfrom
dashboard-honesty

Conversation

@operatoruplift
Copy link
Copy Markdown
Owner

Why this is the biggest honesty bug yet

The dashboard home (/app) was rendering hardcoded data as if it were the user's actual telemetry:

Element What was shown Reality
Stats card "Memories saved: 12.4K · +2.1K today" hardcoded string
Stats card "Security Threats Blocked: 47 · -12% vs yesterday" no security-threats feature exists
Activity feed 5 timestamped events ("Blackwall Blocked SQLi · 2m ago", "DeepRepo Orchestration · 14m ago", etc.) hardcoded array
Gold Agent widget "0.0847 oz · ≈ $278.24 USD · weekly DCA $49.27 · round-ups $9.85 · cashback $3.28" no gold-investment product exists
Header chip "Uplift Core Online" + "Systems optimized. Monitoring N critical events." a 800ms setTimeout
Footer "Global Region: US-EAST-1" the product is local-first; no region routing

A signed-in user looking at this page would believe the system blocked 47 security threats yesterday, indexed 12,400 memories, and is holding $278 of gold for them. None of it is true. Same pattern as the LLM Council fabrication PR #147 fixed.

Changes (one file: app/(dashboard)/app/page.tsx)

Stats

Activity feed

  • Was: real notifications + hardcoded fake events. Empty user saw 5 fake events.
  • Now: real notifications only. Empty user sees "No activity yet · Open the chat or install a helper, your first action shows up here."

Removed: Gold Agent widget

  • The whole 0.0847 oz / $278.24 / DCA + round-ups + cashback panel is gone. There is no gold investment feature shipped.

System status panel

  • "Core Infrastructure" → "System status"
  • Items "API Gateway (Blackwall) / Swarm Router / ATP Settlement Layer / Vector Store" → "Chat / Helpers / Memory / Receipts" (each maps to a live product surface)
  • Removed "Global Region: US-EAST-1" footer

Header

Section labels

  • "Warp Network" → "Quick actions"
  • "Event Stream" → "Recent activity"

Imports

  • Drop unused TrendingUp, ArrowRight, Network icons

Trust impact

Closes the same class of bug as #147 (council UI), #155 (council pitch on /paywall), #156 (council preset on /swarm) — but on the most-visited dashboard surface, where the fabrication touched user-specific account data.

Verified

pnpm exec tsc --noEmit  # exit 0
pnpm check              # 3 passed, 0 failed

Net diff

1 file changed, 43 insertions(+), 59 deletions(-)

Rollback

Single git revert. One file.

The dashboard home (`/app`) was the biggest remaining honesty bug in
the codebase. It rendered hardcoded data as if it were the user's
actual telemetry:

1. Stats card "Memories saved: 12.4K · +2.1K today" (fabricated number)
2. Stats card "Security Threats Blocked: 47 · -12% vs yesterday"
   (no security-threats feature exists)
3. Activity feed with five hardcoded events bearing specific times
   (2m ago, 14m ago, 1h ago, 4h ago, 5h ago) claiming a SQLi was
   blocked, a recursive codebase scan completed on 3 repos, GitHub
   issue sync ran nightly, etc., none of which the user did
4. "Gold Agent" widget showing the user owns 0.0847 oz of gold ≈
   $278.24 USD with weekly DCA $49.27, round-ups $9.85, cashback $3.28
   (no gold-investment product exists)
5. Header chip "Uplift Core Online" + subline "Systems optimized.
   Monitoring N critical events."
6. "Global Region: US-EAST-1" (the product is local-first; there is
   no region routing)

A signed-in user looking at this page would believe the system blocked
47 security threats yesterday, indexed 12,400 memories, and is holding
$278 of gold for them. None of it is true. This is the same pattern
as the LLM Council fabrication PR #147 fixed, just on the home
dashboard.

## Changes

### Stats card
- Drop card #4 "Security Threats Blocked: 47" entirely (no such
  feature)
- Card #3 "Memories saved" now reads `localStorage['memory-engine-v1']`
  for a real count; falls back to 0 for fresh users (was hardcoded
  "12.4K"; the +2.1K-today change blurb is also gone)
- Card #1 "Helpers installed" already pulled from localStorage; the
  hardcoded "+3 this week" fallback is removed for fresh users
- Card #2 "Chat sessions" already pulled from localStorage; the
  hardcoded "Stable" fallback removed for fresh users
- Grid widened from 4 to 3 cards naturally via the lg:grid-cols-4
  layout. The 4-card layout still works, this just shows 3 honest
  cards instead of 3 honest + 1 fabricated.

### Activity feed
- Was: real notifications (up to 3) merged with hardcoded fake events.
  When the user had 0 real notifications, the feed showed 5 fake
  events.
- Now: real notifications only (up to 5). When empty, an empty-state
  card renders: "No activity yet, Open the chat or install a helper,
  your first action shows up here."

### Removed: Gold Agent widget
- The whole 0.0847 oz / $278.24 / DCA + round-ups + cashback panel is
  gone. There is no gold investment feature shipped.

### System status panel
- Title "Core Infrastructure" -> "System status"
- Items "API Gateway (Blackwall) / Swarm Router / ATP Settlement Layer
  / Vector Store" -> "Chat / Helpers / Memory / Receipts" (each
  matches a live product surface)
- Old DEMO badge no longer needed since the items now reflect real
  shipped systems
- Removed "Global Region: US-EAST-1" footer (no region routing)

### Header copy
- Chip "Uplift Core Online" -> "All systems live"
- Subline "Systems optimized. Monitoring N critical events." ->
  "Welcome back. Here's a snapshot."
- "Initialize Agent" CTA -> "Build a helper" (matches #163)

### Section headers
- "Warp Network" (over the quick-actions grid) -> "Quick actions"
- "Event Stream" (over the activity feed) -> "Recent activity"

### Imports
- Drop unused TrendingUp, ArrowRight, Network icons

## Trust impact

Replaces a multi-card fabrication with honest empty states + real
data. Closes the same class of bug as #147 (council UI), #155
(council pitch on /paywall), #156 (council preset on /swarm), but on
the most-visited dashboard surface.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- File still 246 lines (vs 263)
- Empty-state path exercised by setting empty notifications

## Rollback

Single git revert. One file.
@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
website Ready Ready Preview, Comment Apr 27, 2026 6:38am

@operatoruplift operatoruplift merged commit 9a7ac5e into master Apr 27, 2026
4 checks passed
operatoruplift added a commit that referenced this pull request Apr 27, 2026
PR #164 fixed the dashboard home (`/app`) fabrication. Three sibling
pages had the same pattern. Cleaning them up together.

## Changes

### app/(dashboard)/notifications/page.tsx

Was: rendered `INITIAL_NOTIFICATIONS` (5 hardcoded fake notifications,
"Blackwall: 3 threats blocked", "CodePilot Pro updated", "Knowledge
base indexed: 1,247 new documents processed and embedded", etc.) then
optionally prepended any real notifications from `getNotifications()`.
A fresh user would see 5 fake events claiming the system did things
it didn't do.

Now: real notifications only. The existing empty state ("No
notifications") renders for a fresh user. INITIAL_NOTIFICATIONS const
removed entirely.

### app/(dashboard)/workflows/page.tsx

Was: 5 demo workflows with hardcoded run counts (142, 891, 56, 23, 0)
and timestamps ("2h ago", "15m ago", "3d ago", "1d ago", "Never"),
three of them marked `status: 'active'`. Implied the user had Daily
Code Review running 142 times, Issue Triage Bot 891 times, etc.

Now: same 5 starter templates kept (they're useful as inspiration),
all with `status: 'draft'`, `lastRun: 'Never'`, `runs: 0`. The
templates are now honestly templates, not fabricated history.

### app/(dashboard)/analytics/page.tsx

Already carried a small "DEMO" badge and a subline saying "Sample
data, connect Supabase metrics for live analytics". The disclosure was
real but the wording was developer-flavored.

Rewrites:
- subline: "Sample data, connect Supabase metrics for live analytics"
  -> "Example numbers shown here. Real numbers will appear once you
  start using the app."
- "Top Agents" panel title -> "Top helpers" (matches /agents and
  /marketplace renames in #163)

Range/seed sample data + chart left as-is, the disclosure is now
clearer in plain English.

## Trust impact

Closes the same fabrication class as #164 on three more dashboard
surfaces. /workflows still ships templates the user can run, but the
templates no longer pretend to have run already.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed

## Rollback

Single git revert. Three files.
operatoruplift added a commit that referenced this pull request Apr 27, 2026
#165)

PR #164 fixed the dashboard home (`/app`) fabrication. Three sibling
pages had the same pattern. Cleaning them up together.

## Changes

### app/(dashboard)/notifications/page.tsx

Was: rendered `INITIAL_NOTIFICATIONS` (5 hardcoded fake notifications,
"Blackwall: 3 threats blocked", "CodePilot Pro updated", "Knowledge
base indexed: 1,247 new documents processed and embedded", etc.) then
optionally prepended any real notifications from `getNotifications()`.
A fresh user would see 5 fake events claiming the system did things
it didn't do.

Now: real notifications only. The existing empty state ("No
notifications") renders for a fresh user. INITIAL_NOTIFICATIONS const
removed entirely.

### app/(dashboard)/workflows/page.tsx

Was: 5 demo workflows with hardcoded run counts (142, 891, 56, 23, 0)
and timestamps ("2h ago", "15m ago", "3d ago", "1d ago", "Never"),
three of them marked `status: 'active'`. Implied the user had Daily
Code Review running 142 times, Issue Triage Bot 891 times, etc.

Now: same 5 starter templates kept (they're useful as inspiration),
all with `status: 'draft'`, `lastRun: 'Never'`, `runs: 0`. The
templates are now honestly templates, not fabricated history.

### app/(dashboard)/analytics/page.tsx

Already carried a small "DEMO" badge and a subline saying "Sample
data, connect Supabase metrics for live analytics". The disclosure was
real but the wording was developer-flavored.

Rewrites:
- subline: "Sample data, connect Supabase metrics for live analytics"
  -> "Example numbers shown here. Real numbers will appear once you
  start using the app."
- "Top Agents" panel title -> "Top helpers" (matches /agents and
  /marketplace renames in #163)

Range/seed sample data + chart left as-is, the disclosure is now
clearer in plain English.

## Trust impact

Closes the same fabrication class as #164 on three more dashboard
surfaces. /workflows still ships templates the user can run, but the
templates no longer pretend to have run already.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed

## Rollback

Single git revert. Three files.
operatoruplift added a commit that referenced this pull request Apr 27, 2026
…rs (#166)

Five more surfaces still carried fake telemetry or sci-fi cosplay
branding after #164/#165. This is the cleanup PR that closes the
sweep.

## Changes

### app/(dashboard)/agents/[id]/page.tsx (helper detail)

Was: 3 demo helpers with hardcoded
- `sessions: 142` / `2847` / `89`
- `memoryUsage: '2.4GB'` / '512MB' / '1.8GB'
- `status: 'running'`
plus a 5-event ACTIVITY_LOG with timestamps ("2m ago", "15m ago", etc.)
claiming each helper had "Refactor auth middleware completed",
"Memory indexed: 847 new embeddings", "Deployed from Agent Builder"
done on the user's account.

Now: same 3 helpers as starter detail pages but
- `sessions: 0`, `memoryUsage: ','`, `status: 'idle'`
- ACTIVITY_LOG empty by default; the panel renders an honest "No
  activity yet. Run this helper to see results here." placeholder
- "CodePilot Pro" -> "Code Pilot", "Blackwall Guard" -> "Security
  Guard" (last Blackwall reference in user-facing surfaces)

### src/components/ui/CommandBar.tsx (cmd-K palette)

Renamed entries to match the consumer/dashboard rewrites in #154/#163:
- "Go to Agent Store" -> "Go to Helpers"
- "Go to Agent Builder" -> "Go to Builder"
- "Marketing homepage" -> "Public homepage"
- "New Chat" -> "New chat"
- "Build Agent" -> "Build a helper"
- Security entry description "Blackwall security dashboard" ->
  "Encryption, receipts, and activity log"

### app/(dashboard)/integrations/page.tsx

DD.xyz integration `howItWorks` description rewrite. Was: "Powers
Blackwall threat assessment and compliance checks." Now: "used by
security and compliance helpers." (drops the Blackwall brand).

### src/components/providers/AgentProvider.tsx

`MOCK_AGENTS` was 4 agents named "Founder Ops" / "Growth Lead" /
"DevRel" / "Support Bot" with status "online" / "busy" / "offline"
and descriptions like "Orchestrating company operations" that
implied real ongoing operations on the user's account.

Now: 4 helpers named after what they actually do,
- "Inbox helper", "Calendar helper", "Research helper", "Reminders"
all with status "online" since they're available to run, not
pretending to be running tasks behind the scenes. Default activeAgent
flipped from "founder-ops" to "inbox" so the consumer use case is
front and center.

### app/(dashboard)/onboarding/page.tsx

Starter helper renames: "CodePilot" -> "Code Pilot", "Research Bot"
-> "Researcher", "Security Guard" desc rewrite to match
agents/[id]/page.tsx.

## Trust impact

Final pass on the fabrication class started in PR #147. After this
merges, a grep for "Blackwall|CodePilot|Founder Ops|Warp Network|
Uplift Core|Gold Agent" returns zero hits in user-facing surfaces.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- Final fabrication sweep clean (only hit is the comment on
  notifications/page.tsx documenting what #165 removed)

## Rollback

Single git revert. Five files.
operatoruplift added a commit that referenced this pull request Apr 27, 2026
…167)

Two improvements in one PR.

## (1) Trust-gate coverage 11/44 -> 16/44

Five small routes adopted the @/lib/apiHelpers withRequestMeta pattern
that the larger /api/tools/* routes already use (PR #123) and the
observability sweep extended to the receipts/memory/agents/
notifications/audit families (PR #130). Now every response from
these routes carries `X-Request-Id`, supporting the request-id
propagation contract trust-gate enforces.

Routes:
- app/api/providers/route.ts        (6 lines)
- app/api/capabilities/route.ts    (25 lines)
- app/api/receipts/public-key/route.ts (26 lines)
- app/api/health/llm/route.ts      (27 lines)
- app/api/dashboard/stats/route.ts (31 lines)

## (2) Fix the residual fabrication in /api/dashboard/stats

While adding apiHelpers I found one more fabrication leftover: when
the route's auth check fails, it was returning a hardcoded fallback
payload:

  {
    activeAgents: 14,
    chatSessions: 8,
    memoryNodes: 12400,
    securityBlocks: 47,
  }

These are the **exact same fake values** PR #164 removed from the
rendered dashboard. The dashboard now reads from localStorage
directly so it doesn't call this route, but anything else that
hits /api/dashboard/stats unauthenticated still got the lie.

Now: returns zeros on the unauthenticated path. No fake demo data.

## Trust impact

Closes the dashboard fabrication arc started in #164/#165/#166. Adds
the request-id contract to 5 more routes.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- trust-gate: 16/44 route files (was 11/44)

## Rollback

Single git revert. 5 files.
operatoruplift added a commit that referenced this pull request Apr 27, 2026
…on (#173)

Trust-gate 37/44 -> 41/44 (~93%). Includes one residual honesty fix.

## Routes adopted

| Route | What it does |
|---|---|
| app/api/debug/subscription/route.ts | Admin paywall diagnostic |
| app/api/debug/solana-wallet/route.ts | Admin x402 wallet diagnostic |
| app/api/tools/x402/route.ts | x402 fetch proxy + retry-with-proof |
| app/api/audit/publish-root/route.ts | Merkle-root publish to Anchor program |

## Honesty fix: x402 "charge" action retired

While adopting apiHelpers on app/api/tools/x402/route.ts I caught a
residual fabrication in the legacy "charge" action. It was building a
chargeRecord with `tx_signature: \`x402-devnet-${Date.now()}\``, a
fake transaction signature that mimicked a real on-chain identifier,
then logging it as `status: 'approved'`. The same fabrication class as
the council UI (#147), the dashboard widget (#164), and the
dashboard/stats fallback (#167).

Real settlement lives in /api/tools/x402/pay where a genuine ed25519
receipt is produced. Nothing in the codebase calls the legacy charge
action (grep'd to confirm). Replaced the action with a 410 Gone +
nextAction pointing callers at /api/tools/x402/pay.

The "fetch" and "retry_with_proof" actions are unchanged; both are
pure proxies that don't fabricate anything.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- trust-gate: 41/44 (was 37/44)
- grep for `x402-devnet-`: zero hits

## Rollback

Single git revert. 4 files.
operatoruplift added a commit that referenced this pull request Apr 27, 2026
Locks in the user-specific fabrication fixes that PRs #164/#165
shipped to /app, /notifications, /workflows. If a future PR drifts
back toward fake stats, fabricated activity, or zombie "Blackwall"
language, CI fails before merge.

## tests/e2e/dashboard-honesty.spec.ts (new)

Three scoped specs running against the dashboard-gated routes via
the auth-bypass helpers from #151.

| Test | Asserts |
|---|---|
| /app dashboard | "Helpers installed / Chat sessions / Memories saved" labels present, no "12.4K", "47", "Security Threats Blocked", "Gold Agent", "0.0847", "Blackwall", "Uplift Core Online", "Warp Network", "Event Stream", "US-EAST-1" anywhere in the rendered DOM. Activity feed is empty-state OR real notifications, never the old 5-event fake feed. |
| /notifications | No "Blackwall: 3 threats", no "CodePilot Pro updated", no "1,247 new documents". |
| /workflows | No "142 runs" / "891 runs" hardcoded fake counts. |

The test deliberately uses contextual assertions rather than blanket
banned-string match because some numerals are legitimate (e.g. "47"
on its own can appear elsewhere; what we're banning is "47 Security
Threats Blocked" together).

## .github/workflows/ci.yml

dashboard-honesty.spec.ts joins consumer-copy + chat-honesty in the
hermetic Playwright run.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- pnpm exec playwright test dashboard-honesty.spec.ts: 3 passed (37s)

## Rollback

Single git revert. 2 files.
operatoruplift added a commit that referenced this pull request Apr 27, 2026
The legacy "confirm" fall-through path on POST /api/subscription was
a real security gap. Any authenticated user posting:

    POST /api/subscription
    Authorization: Bearer <valid-privy-jwt>
    Content-Type: application/json

    { "tx_signature": "anything-here" }

would be marked tier=pro, status=active without any on-chain
verification. The TODO at line 159 admitted it: "Verify the Solana
tx on-chain before activating. For devnet/demo, we trust the
client-provided signature." Same fabrication class as the council
PRs cleaned up (#147, #155, #156, #164, #167, #173).

No code path calls this fall-through (`grep -rn "tx_signature.*\
subscription"` returns zero in app/, src/). The paywall page uses
action="create_invoice" exclusively, and real settlement runs
through /api/access/verify-payment which DOES call verifyPayment()
against the Solana RPC.

Closed the path with HTTP 410 Gone + a nextAction pointing callers
at /api/access/verify-payment, the route that actually verifies the
on-chain tx.

The two known-good actions ("create_invoice" and "dev_simulate")
are unchanged.

## Verified

- pnpm exec tsc --noEmit: clean
- pnpm check: 3 passed, 0 failed
- grep -rn "tx_signature.*subscription" returns 0 callers

## Rollback

Single git revert. One file.
operatoruplift added a commit that referenced this pull request Apr 28, 2026
…#209)

Both routes were serving hardcoded "demo until API key configured"
data with zero internal callers:

- /api/risk -> lib/webacy-risk.ts returned overall: 87, grade: 'A',
  flagged: false, sanctions: false for any wallet/contract/transaction.
  A "your wallet is safe" answer regardless of input.

- /api/gold -> lib/oro-grail.ts returned balanceOz: 0.0847,
  balanceUsd: 278.24 — exactly the values that
  tests/e2e/dashboard-honesty.spec.ts bans (Gold Agent retired in #164).
  The dashboard widget was retired but the API + lib survived.

Both routes now return 410 Gone with a clear nextAction, mirroring the
pattern from #173 (x402 charge) and #182 (subscription confirm).

Both libs deleted (no callers).

DD.xyz integration entry on /integrations: status updated from
"available" to "coming_soon" since the lib backing it returned fake
data. Now matches the truth.

tests/e2e/request-id-runtime.spec.ts: /api/risk expectStatus updated
[400, 401] -> [401, 410]. Added /api/gold probe with [401, 410].
Hermetic spec count stays at 17 (just adds a probe to an existing spec).
operatoruplift added a commit that referenced this pull request Apr 28, 2026
…r fake (#210)

The /memory dashboard page initialized with 6 hardcoded fake "memory
nodes" with detailed metadata:
  - "Operator Uplift Architecture" (1240 vectors, 48KB)
  - "Security Whitepaper" (2100 vectors, 156KB)
  - "User Feedback Q1 2026" (1800 vectors, 92KB)
  - ...etc, totaling ~6900 vectors of fabricated "indexed memory"

A fresh user landed on /memory and saw 6 documents that don't exist.
Same dashboard fabrication pattern that #164 cleaned up on /app, /agents,
and /workflows. /memory just wasn't covered.

Worse: addNode() generated a *random* vector count
(`Math.floor(Math.random() * 2000) + 100`) and toasted "Title indexed
with 1247 vectors" — implying real embedding work happened when the
page never calls lib/memoryEngine.ts at all.

Three changes:
1. DEMO_NODES -> empty array (fresh user sees the empty state already
   built into the page: "No knowledge indexed yet").
2. addNode() now writes vectors: 0, lastIndexed: 'Pending', size:
   'Unknown', and the toast says "Embeddings will be computed once the
   indexer is connected" — the truth.
3. Header gets the same DEMO badge + disclosure copy as /analytics:
   "Add knowledge sources here. Embedding + search will activate once
   the indexer is connected."

Locked in via a new test in tests/e2e/dashboard-honesty.spec.ts that
asserts the four most distinctive fake titles never appear on a fresh
/memory load. Hermetic spec count stays at 17.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant