← Documentation index Architecture guide › observability

Metnos

Operational observability
Seeing system state without mistaking a view for a source of authority.

Metnos provides two separate facilities. The chat's Settings page is the current administration interface and refreshes its data on each request. runtime/observability.py instead produces a static HTML file for local diagnosis. That file does not feed Settings, does not refresh itself, and is not served as a chat page.

Contents

  1. A natural-language example
  2. The two surfaces
  3. Settings in the chat
  4. The static HTML snapshot
  5. Data collected by the snapshot
  6. Access, users, and confidentiality
  7. Generation and lifetime
  8. Verification and canonical sources

1. A natural-language example

Ask Metnos with a request such as:

Show me where I can check the latest turns and service status.

A useful answer should first give the visible route in the chat: Settings > Activity > Turns for recent requests and Settings > System > Services for configured services. If the question came from Telegram, this route must be opened in the Metnos web chat: Telegram does not embed administration pages.

Only after this practical instruction should the answer explain APIs, records, or files. The static snapshot is appropriate for an explicitly requested technical diagnosis; it is not the ordinary route for chat users.

2. The two surfaces

SurfaceRefresh behaviourAccessPurpose
Settings (/admin)Data is read again when the page is opened or refreshed.Requires the administrator role enforced by HTTP middleware.Inspection and administrative controls for the running installation.
Static snapshot (runtime.observability)Captures the instant when the command runs.Local file; protection depends on filesystem and machine permissions.Offline diagnosis across six historical data sources.

The two surfaces must not be merged into a single description. Settings uses its own routes and view models; only the command-line interface calls the static generator, and the HTTP server has no caller for it.

3. Settings in the chat

The Settings landing page summarises version and uptime, turns over the last 24 hours, proposals, executors, scheduler activity, Safety signatures, and users. Detail pages keep different operational questions separate:

Route in the chatMain information
Settings > Activity > TurnsIdentifier, time, channel, actor, steps, outcome, duration, and request.
Settings > Activity > SchedulerTask runs, outcome, and duration.
Settings > System > ServicesServices in the canonical registry, status, and admitted controls.
Settings > System > ModelsEffective redacted LLM, embedding, and VLM configuration: LLM and VLM can be edited and restored; embedding is view-only.
Settings > System > DevicesPaired devices, presence, and revocation.
Settings > System > UsersUsers, roles, channels, and administrable preferences.

runtime/ui_surfaces.py is the canonical editorial description of visible pages and their navigation routes. Tutor consumes the same registry: a structural UI change requires a registry update, a navigation guide update, and a rebuilt Tutor index.

4. The static HTML snapshot

render_dashboard(out_path) queries local sources and composes one document with embedded CSS, no JavaScript, and no WebSocket. Sections are ordered as follows: tests, Mnestoma, pairings, recent turns, Vaglio decisions, and scheduler.

Each collector handles an unavailable source separately. The page can therefore be produced when one section is empty or reports an error. This makes a partial snapshot readable; it does not make missing data evidence that the corresponding component is healthy.

The generated document currently uses Italian labels and lang="it". It is not a localised chat surface and must not be presented as one.

5. Data collected by the snapshot

SourceDisplayed projectionConfigured location
MnestomaCounts, active and proto edges, recent events.Mnestoma's database, normally below PATH_WORKSPACE/.mnestoma.
PairingsChannel, sender identifier, level, timestamps, pairing author, and revoked count.DB_PAIRINGS below PATH_USER_STATE.
TurnsLatest fifteen turns: request, outcome, step count, and beginning of the answer.PATH_TURNS below PATH_USER_DATA.
VaglioLatest twenty decisions: executor, score, outcome, and abbreviated reason.PATH_USER_DATA/vaglio.
SchedulerEnabled tasks, schedule, latest run, and outcome.PATH_USER_STATE/scheduler_v2.sqlite.
Registered testsModules, enabled cases, latest status, and largest modules.PATH_RUNTIME/testing/tests.db.

Limits are fixed by the generator rather than exposed as CLI options: at most five daily turn files, three Vaglio files, and distinct row or event limits. A complete analysis must query the authorised source instead of inferring totals from this page.

6. Access, users, and confidentiality

7. Generation and lifetime

From the installation root, using the Metnos Python environment:

PYTHONPATH=runtime ./.venv/bin/python -m observability render
PYTHONPATH=runtime ./.venv/bin/python -m observability render --out /chosen/path/dashboard.html

The default destination is PATH_WORKSPACE/dashboard/index.html. The command reports the written path and exits. There is no built-in periodic refresh: generation time and content remain unchanged until the command runs again.

The file is derived output. It can be removed by deleting only the selected output path after confirming that no process uses it; removing it does not delete any operational source.

8. Verification and canonical sources

Focused tests for the static generator live in tests/runtime/runtime/test_observability.py. They verify, among other things, that executor names, requests, and responses cannot introduce active markup into the file. HTTP and end-to-end tests cover administration pages separately; this guide does not freeze a test count that would become stale.