Skip to main content
OrbitPilot

Memory Status — one page, one truth (BL-428)

What this page is

OrbitPilot already tracked, in several different places, what it remembers about you: a build card on the dashboard, small icons next to each Blink, and a line it adds to its own answers when memory is out of date. The owner's own words on the day this shipped: an update time that is silent about SCOPE — "updated today but cannot access" — is a truthful sentence that still leaves you confused. The Memory Status page (/orbitpilot/memory-status/) puts all of it on one page: when memory last changed and how, every source currently in it with counts, and — for anything missing — the honest reason why, in plain language.

What it shows

  • Last update. The time memory last changed and the method — a full rebuild, a quick update, or an automatic/manual update from a single saved change — plus, if memory is stale, degraded, or has never been built, the exact sentence OrbitPilot would attach to an answer right now.
  • In your memory. Every source with real content in memory — Blinks, Goals, Projects, Businesses, files, and more — with an item count and when it was last built.
  • Not in your memory. Every other available source, each with an actionable reason: off site-wide, not on your plan (upgrading would add it), files waiting to be moved into the protected OrbitPilot Files folder, or simply not picked up by a build yet.

Refreshing memory from this page

Since BL-435 the Last update card carries the two refresh actions itself — ⚡ Quick update (re-reads only what changed since the last build; cheap) and 🔄 Full rebuild (re-reads and re-embeds everything; uses more AI credits) — so nobody has to leave the page to act on what it shows. They are the very same controls as the OrbitPilot chat window's ☰ menu → Memory, by the owner's rule "do not double the code": ONE shared template partial (templates/_orbitpilot_rebuild_controls.html) rendered on both surfaces, ONE endpoint (orbitpilot_rebuild_memory, POST mode=soft|hard), the same confirmation dialog, the same stuck-build healing on click (BL-404 reaper) and the same live progress ring (BL-410). The buttons are wired by document-level [data-op-rebuild] delegation in static/js/orbitpilot-widget.js; because that script is lazy-loaded, orbitpilot-loader.js queues a click that lands before it has loaded and replays it (rebuildFromButton), the same way it protects the chat button's first click. When a build completes, this page reloads itself so the "Last update" facts re-read from get_memory_status_page instead of going stale. Guards: orbitpilot/test_memory_status_page.py::RebuildControlsTests fail the moment the buttons are copied into a second template or a second rebuild route is registered.

Where to find it

A "🧠 Memory status" link sits in the OrbitPilot chat window's bottom toolbar — the same row as New / History / Copy / This chat — so it is one click away from every conversation, docked or full-page. Guests see the same link, but it leads to account creation instead, since there is no personal memory to report on yet.

How this works — for admins

Nothing to configure today. The page is open to every signed-in user; a later plan-gate (e.g. restricting it to higher tiers) is one Feature Registry row away — register a Feature with key orbitpilot_memory_status_page and assign or disable it, no code change needed.

Staff and superuser accounts see an extra notice on the page: their account bypasses plan gates entirely (plans.services.get_effective_limits hands staff every flag unconditionally), so what a staff account sees is not what a same-plan non-staff user would see. This exists so an admin never mistakes their own bypassed view for what a real user's page looks like.

How this works — for developers

orbitpilot/services.py::get_memory_status_page(user) is the entire computation, and it AGGREGATES ONLY — it calls the exact same functions every other surface already uses, so this page can never disagree with them: get_last_build/get_last_completed_build, memory_is_stale, build_notice.ask_honesty_note (BL-405, returned verbatim), and resolve_build_sources + _plan_gate_reason (#597 / BL-410-P1, the same reasons build_user_snapshot hands the model mid-conversation). Per-source counts come from one GROUP BY over OrbitPilotMemoryChunk, excluding get_rag_disabled_keys() the same way pipeline/retrieve.py excludes them — a source an admin switched off after it was built still has rows in the table, and this page must not call those rows "in memory" when retrieval will never search them.

View: orbitpilot.views.orbitpilot_memory_status, URL name orbitpilot_memory_status. Template: orbitpilot/templates/orbitpilot/memory_status.html. Parity is pinned by orbitpilot/test_memory_status_page.py — a test creates a real chunk row and asserts the page's count equals a plain query over the same table, so the page cannot silently start recomputing its own numbers.

Related pages

Docshub: "Per-Blink memory status icons" (BL-417, the same vocabulary and wording family), "Your memory stays honest" (BL-405). docs/orbitpilot/TASKS.md.

🪐 OrbitPilot

Create a free account and I'll remember your conversations — sign up

🧠 Memory status