feat(webui): AI-provider connections and evidence-backed insights (Closes #650)

Add Phase 4 advisory surfaces for declared AI-provider connection status
(no secrets, no live probe claims) and operational insights derived only
from durable traffic, health, provider, and analytics evidence.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
2026-07-25 16:53:36 -04:00
co-authored by Claude Opus 4.8
parent 76f293eb28
commit 983e8ac2c7
6 changed files with 1412 additions and 11 deletions
+54 -1
View File
@@ -83,7 +83,10 @@ status, onboarding checklist state, and the fail-closed error payloads (#635).
| `/inventory` | Phase 1 shell stub — unified inventory (backed by #636) |
| `/timeline` | Phase 1 shell stub — workflow event timeline |
| `/policy` | Phase 1 shell stub — capability/role policy placeholder |
| `/insights` | Phase 1 shell stub — operational insights placeholder |
| `/providers` | AI-provider connection status (#650) — declared registry only, no secrets |
| `/api/v1/providers` | JSON provider connections; `502` when the registry cannot be loaded |
| `/insights` | Evidence-backed operational insights (#650) — advisory only |
| `/api/v1/insights` | JSON insights export with evidence refs and source availability |
Most routes are GET-only. POST/PUT/PATCH/DELETE return `405` with
`read-only-mvp`, except `/audit` and `/api/audit` which accept POST for
@@ -327,6 +330,56 @@ Honesty rules specific to this view:
The write-time redactor is a narrow denylist and is not relied on. The field
itself is kept — it is the `#630` evidence naming which daemon was killed.
## AI providers and operational insights (#650)
`/providers` and `/insights` are the Phase 4 **advisory** surfaces for AI-provider
connections and evidence-backed operational findings. They never expose API keys,
never mutate Gitea, and never authorize review, merge, or close.
### Provider connections (`/providers`)
Status is taken from the **worker registry** declaration (`webui/data/workers.registry.json`
or `WEBUI_WORKER_REGISTRY`):
| Field | Meaning |
|-------|---------|
| `connection_status` | `declared_available` or `declared_unavailable` from the registry `available` flag |
| `models` | Declared model list only (not a live vendor enumeration) |
| `worker_count` / `enabled_worker_count` | How many worker instances name this provider |
| `secrets_exposed` | Always `false` — credentials are never loaded |
Live executable health is **not** probed here (that belongs to the provider adapter
framework). The page states this probe limit explicitly so a green badge is not
misread as a process heartbeat.
`GET /api/v1/providers` returns the same model (`schema_version: 1`). It answers
`502` when the registry cannot be loaded so consumers cannot treat a fail-closed
payload as “no providers configured”.
### Operational insights (`/insights`)
Insights are pure functions over durable console evidence:
| Kind | Evidence source |
|------|-----------------|
| `blocked_queue_pressure` | Traffic control blocked bucket (issue/PR numbers + reasons) |
| `controller_attention` | Traffic control `needs_controller` items |
| `stale_runtime_risk` | System-health stale_runtime / mutation_safe |
| `provider_without_workers` | Declared-available providers with zero workers |
| `analytics_failure_pressure` | Analytics events with failure status (when loaded) |
Rules:
* Every insight carries at least one evidence ref (`kind` + `ref` + `detail`).
Evidence-less insights are refused, not emitted.
* `advisory_only` is always true; `claims_action_completed` is always false.
* Missing sources appear under `sources_unavailable` — never as a silent empty
“all clear”.
* Titles and details pass through console redaction before display.
`GET /api/v1/insights` exports the same model. The HTML page always renders
interpretation limits so operators know these cards do not override workflow gates.
## System-health dashboard (#639)
`/system-health` renders the same snapshot the `/api/v1/system/health` API