Skip to content

Admin Control Panel v2

Status: LIVE since 2026-07-04 · App: rabbithall · URL: admin.joaoluisbrazao.cloud/admin/dashboard

The admin control panel was rewritten on 2026-07-04 to serve João as a manager of the whole back office — surfacing critical problems, curation work, and duplication issues in one place — rather than as a sysadmin console. The classic dashboard (admin_dashboard.html) was deleted (archived in Workspace/90-Archive/); the canonical light-theme CSS variables now live in cockpit.html.

The three panels

1. Control Center — /admin/dashboard

Template cockpit.html, shared handler _render_cockpit() (also serves /admin/cockpit; /admin/dashboard-classic redirects here).

Six action-oriented sections:

Section Purpose
Act Now Critical/urgent items needing a decision today
Curation Hubs Entry points to the Gamine and Brain curation hubs
Applications The live apps (Expense Report, Gamine, TCN, brains…)
System & Operate VPS, runs, audit, tasks, inbox
Reference Compact chip row — docs, catalogs, dashboards
People & Community Compact chip row

The top strip is live, not a snapshot: _cockpit_live_stats() reads Vikunja (critical = priority 5 count, total pending, top-3 critical titles) and the unified review count (discovery_queue review + brain_staging quarantine + gamine intelligence_six_eyes verdict='review'). Every source is optional — on failure the template falls back to the seed values.

Cards are data-driven from /app/data/cockpit_seed.json (groups[].items[]), read per-request so seed edits go live without a restart. Deploy gotcha: the seed is not bind-mounted — edit the disk source /opt/rabbithall/data/cockpit_seed.json AND docker cp into the container, then chown appuser:appgroup + chmod 640. Templates are bind-mounted; rh-deploy --app --restart clears the Jinja cache. Reload infra-nginx after any backend restart.

2. Curation Hubs — /admin/curation/hub/gamine and /admin/curation/hub/brain

One parameterized template (curation_hub.html). Each hub is an editable topology list:

  • Gamine edits gamine_brain.search_terms.category — general / scientific / news / partners (competitors read-only).
  • Brain edits down_rabbit_hole.search_topology.domain — geopolitics / tcn / crypto / ai.

The 11 former "Brain & Curation" cards are folded into these two hubs as links.

3. Unified Review Queue — /admin/review-queue

Template review_queue.html. Normalizes three sources into one Six Eyes inbox:

  1. brain_staging quarantine (brave_search staging rows)
  2. discovery_queue rows with six_eyes_verdict='review'
  3. Gamine intelligence_six_eyes rows with verdict='review'

Actions per item: Ingest / Forget / Deep-research (deep-research enqueues a harvest_targets row for brain items, or an inactive proposed search_terms row for Gamine).

Canonical Six Eyes routing thresholds (0–10 scale, defined in app.py, mirrored via SIX_EYES_DISCARD_MAX / SIX_EYES_INGEST_MIN env vars in gateway skills):

  • score ≤ CURATION_DISCARD_MAX (3.0) → auto-discard
  • score ≥ CURATION_INGEST_MIN (6.0) → auto-ingest
  • in between → human review in this queue

/admin/search-quarantine redirects here since 2026-07-05 (both the page and its POST action route; the shared helper _sq_apply_action remains in use by the review queue).

Supporting skill

gamine.six-eyes-scorer (jb-skills-gateway) scores unscored Gamine intelligence_items 0–10 on cron and routes by the thresholds above. Adapted from search.six_eyes_scorer; uses the LiteLLM standard alias.

Pipeline fixes shipped with v2 (2026-07-04)

Three silently-broken pipelines were found and fixed during the rewrite:

  1. _discovery_conn pointed at the deleted jb_knowledge DB — all discovery endpoints were dead. Now down_rabbit_hole.
  2. /admin/search-quarantine actions used the Gamine app DB (no brain_staging table) — approve/reject never worked. Fixed before the page was superseded.
  3. The harvest worker's WHERE domain IS NOT DISTINCT FROM 'tcn' never matched 615 NULL-domain search_topology rows; domain is now backfilled and stamped on insert.

Related migrations (reversible): search_terms.category added + backfilled; search_topology.domain backfilled (restore table search_topology_domain_bak_20260704).

Known gaps

  • discovery_findings.brain_node_id is never populated by any process (verified 2026-07-05: 0 rows had it set; no writer exists anywhere in /opt). "Ingest"/promote on a discovery_queue item flips review_status='promoted' and writes audit rows, but no consumer turns promoted rows into actual brain nodes. Decide whether this queue should feed real ingestion (needs a new consumer skill) or is a triage/audit layer by design.
  • The 1,053 legacy verdict='approve' rows stuck at review_status='pending' were backfilled to promoted on 2026-07-05 (review_notes tagged [auto-backfill 2026-07-05]) — subject to the same gap above.
  • Dashboard v2 commits (rabbithall 2ec915d, gateway ff10fde) live on feature/harvest-loop, not yet merged to main (#960 repo drift).