Complements the task-granular background_work with the async-delegation
UNIT count (each dispatch/batch = 1), recovering the pool-slot semantics
active_count() gives. Together: background_work = real concurrent subagent
load (batch expanded), background_delegations = slot pressure to alert
against delegation.max_concurrent_children. Registered in metric_names,
documented, and covered by a task-vs-unit contract test.
A delegate_task fan-out batch occupies ONE async-pool slot by design, so
active_count() (unit/slot count) reports a 3-task batch as 1 — which
undercounts real concurrent subagent load on the background_work metric.
Add active_task_count() that expands a running batch to its child count
(N-task batch -> N, single -> 1) and switch the background_work reader to
it. active_count() is unchanged (capacity semantics preserved). Adds a
contract test for the unit-vs-task distinction and documents both counts.
active_agents counts foreground turns + cron + API runs but never the
backgrounded delegate_task subagents / terminal(background) processes /
kanban workers tracked only for scale-to-zero. Emit them as a distinct
content-free gauge so the fleet dashboard can show subagent/background
load per peer. Best-effort, sums async_delegation.active_count +
process_registry.count_running; 0 if a source is unavailable.
(cherry picked from commit 1b7ec684e253651a5aa5760b3bd527a3073ce207)
The cron health snapshot failure path logged only at DEBUG, so a cron
telemetry regression would silently drop all hermes.cron.* metrics while
gateway health metrics kept flowing. Promote to WARNING with the
exception *type* name only (no message text, preserving the no-raw-error
contract); keep the traceback on DEBUG.
(cherry picked from commit 1c9a3e737b7c57fa9886bc927f1623753a9a811b)
Salvages the event-spine foundation from feat/telemetry-observability
(emitter, typed events, OTLP streaming, redaction — authorship preserved in
the preceding commits) and scopes it to the plane enterprise operators need
today: gateway Service Health Monitoring plus redacted Operational
Diagnostics, exported over OTLP.
Dropped from the salvaged branch, deliberately:
- run/model/tool trajectory capture (plugins/telemetry hooks, tel_spans)
- the local JSONL + state.db tel_* store (monitoring is egress, not storage)
- usage rollups/metrics, /insights integration, bulk export
- hermes telemetry CLI (replaced by hermes monitoring status)
Those planes — shared client usage metrics and enterprise trace telemetry —
are being designed on the NeMo Relay integration with distinct consent,
policy, and export boundaries; this keeps the monitoring plane content-free
and independently enableable.
Renames agent/telemetry -> agent/monitoring, config telemetry.* ->
monitoring.*, and pins the otlp extra at OpenTelemetry 1.39.1 (matching
uv.lock; 1.30.0 conflicts with mistralai>=2.4 on opentelemetry-api).