Reading `Overall: degraded` on a fresh analyst install — driven by
server-side operator warnings (stale tables, session-pipeline cadence,
BQ billing-project config) that the analyst can't act on — erodes trust
in the install. The role-aware headline routes operator-only warnings
through a secondary line so they're not invisible, but they no longer
drive the headline an analyst sees.
Server-side (`app/api/health.py`):
- Per-check `audience: "analyst" | "operator"` tag on every entry in
`/api/health/detailed` services dict.
- New top-level `caller_role` field (derived from `user.is_admin`) so
the client knows which aggregation to display.
- New top-level `overall_analyst` field — analyst-only aggregation
available to clients that don't want to recompute it.
Client-side (`cli/commands/diagnose.py`):
- When the server reports `caller_role`, analyst aggregations exclude
audience=operator checks from the headline. Analyst-side warnings
AND server-side errors still escalate (errors are universal).
- Secondary line surfaces operator warning count so they're visible:
"Overall: healthy (analyst-side); 2 operator-side warnings".
- Admin/operator role auto-promotes to full aggregation; analysts can
manually opt in via `--include-operator-checks` flag.
- Legacy servers without `caller_role` keep the pre-#345-B full
aggregation — no silent regression against older deployments.
Audience defaults (`_AUDIENCE` map in health.py):
- analyst: duckdb_state
- operator: db_schema, data, users, bq_config, session_pipeline
Tests: 4 new in TestAnalystAudienceFilter (analyst-only filtering,
admin auto-promote, --include-operator-checks opt-in, legacy server
fallback). 26/26 diagnose + health tests pass.