Repository navigation
09 Admin Panel
A zero-dependency local dashboard: corpora, index quality, telemetry, settings. Standard-library http.server only — the same «works where Python works» principle as the rest of RAGRAF.
python tools/ragraf-admin.py --no-browser # don't open the browser automatically
python tools/ragraf-admin.py --port 8777 # default port- Binds
127.0.0.1only — by design; there is no network interface. - At startup the console prints a one-time access token (
secrets.token_urlsafe(24)). - Reads need no token; all mutations are POST + token (checked with
secrets.compare_digest; body capped at 1 MB). No setting changes via link navigation (protection against accidental clicks and browser prefetch). - Heavy data is cached 5 s server-side (
/api/cache/clearflushes).
⚠️ Threat-model caveat (defect C-01, roadmap R-SEC-1): the page auto-fetches the token fromGET /api/token, which answers any local client without authentication, and the server does not validateHost/Origin. Practical meaning: the token protects against accidents (a random tab clicking around), not against a malicious local process or DNS-rebinding. Until R-SEC-1 (Host/Origin allow-list + manual token entry / pairing), do not run the panel on shared machines with untrusted local users, and never port-forward it.
| Block | Source | Contents |
|---|---|---|
| Developments (catalog) |
catalog.json + per-corpus check |
revision, checksum, hash_matches (live recompute without indexing), file counts, store sizes per SQLite file and per table |
| Usage |
usage_call telemetry |
calls per operation, facts, facts-with-span share, characters, token/saved-reads estimates (labeled as estimates) |
| Quality | index internals | vector-norm distribution, chunk-size distribution vs budget (chunks.total, max_tokens, over_budget), signature truncation counters, health verdict |
| Settings | global settings.json + per-project config |
guard thresholds (reindex_after_changes, full_reindex_after_changes, reindex_interval_minutes) and indexing params |
The quality block exists because of measured defects: «score = 0.000 for all vectors» (unnormalized embeddings + naive distance→score) and «an 11 331-token chunk» were invisible as errors — they looked like empty results. Norm distribution and chunk sizes in the panel diagnose both at a glance (article §14, recommendation 2 — implemented).
History note: the quality block once read
chunk_map/ft_chunkfrom the graph DB instead of the lexical one, and the caught exception rendered as «no data» (article defect №11 — «the most dangerous kind: error handling turned a failure into an empty value»). It also once declared unnormalized vectors a defect although the scoring formula already accounts for norms (defect №12 — «a warning about a nonexistent problem is worse than no warning»); the check is informational now.
| Method | Path | Auth | Purpose |
|---|---|---|---|
| GET | / |
— | the single-page UI (inline PAGE_HTML + /style.css + /app.js) |
| GET | /api/state |
— | full dashboard state (catalog + per-corpus usage/quality + settings) |
| GET | /api/settings |
— | settings projection |
| GET | /api/health |
— | {ok, version, root} |
| GET | /api/token |
— | |
| POST | /api/settings/global |
token | save global thresholds — validated (settings.validate: bounds, enums, cross-field full > fast) |
| POST | /api/settings/project |
token | save project index: keys — line-wise edit preserving comments, timestamped .bak backup, validation |
| POST | /api/cache/clear |
token | flush the 5-s state cache |
Validation failures return 400 with the reason list; unknown routes 404. Settings changes apply at the next freshness check — the current revision never mutates (P1).
admin/static/app.js (vanilla JS, no frameworks, no external resources — project rule: no CDN, colors only through tokens) + admin/static/style.css. The UI is currently Russian; the EN pass is roadmap R-I18N-1 (defect E-08).
# panel won't start: port busy
python tools/ragraf-admin.py --port 8788
# scripted health probe
curl -s http://127.0.0.1:8777/api/health
# settings rollback (project config)
# backups live next to the config: <name>.yaml.bak.<YYYYmmdd-HHMMSS>-settingsLive checks of the panel in the author's environment ran via tests/check_admin_agents.py / check_admin_dedupe.py (not shipped); a portable smoke test is: start the panel → GET /api/health → GET /api/state → change a threshold via POST with the token → confirm the .bak file and the «applies at next freshness check» note.
Next: Troubleshooting →