Status: Frozen (implemented backend contracts reconciled) Date: 2026-02-19 Working directory: docs/modules/ui/v2-rewire Sprint: 20260218_005, task R0-02
Define Security and Risk -> Advisory Sources as the decision-impact view of advisory-source health. This is the security gating interpretation surface; operations on connectors/mirrors belong to other domains.
- Freshness routes are implemented in Concelier:
GET /api/v1/advisory-sourcesGET /api/v1/advisory-sources/summaryGET /api/v1/advisory-sources/{id}/freshness
- Policy impact/conflict routes are implemented in Policy Gateway:
GET /api/v1/advisory-sources/{id}/impactGET /api/v1/advisory-sources/{id}/conflicts
- Persistence backing is implemented via:
src/Concelier/__Libraries/StellaOps.Concelier.Persistence/Migrations/004_add_advisory_source_freshness_projection.sqlsrc/Concelier/__Libraries/StellaOps.Concelier.Persistence/Migrations/005_add_advisory_source_signature_projection.sqlsrc/Policy/__Libraries/StellaOps.Policy.Persistence/Migrations/005_advisory_source_projection.sql
- Frontend Security & Risk consumption is implemented via:
src/Web/StellaOps.Web/src/app/features/security-risk/advisory-sources.api.tssrc/Web/StellaOps.Web/src/app/features/security-risk/advisory-sources.component.ts- Endpoint-driven table/summary/detail state rendering (hard fail, degraded, conflict, and empty behaviors).
- Detail-panel advisory statistics now bind to backend contract fields (
totalAdvisories, signedAdvisories, unsignedAdvisories, signatureFailureCount) instead of placeholders.
| Field / Action | Owner domain | Rationale |
|---|
| Source name, family, description | Integrations | Connector catalog owner |
| Credential / connectivity status | Integrations | Connector health owner |
| Test connection action | Integrations | Links to Integrations connector detail |
| Mirror and freshness operation actions | Platform Ops | Mirror workflow owner |
| Last successful ingest, freshness age, freshness SLA | Platform Ops (source), Security & Risk (display) | Platform Ops publishes freshness facts; this screen reads and interprets for gating impact |
| Signature / trust status | Administration (Trust & Signing, source), Security & Risk (display) | Administration manages trust keys; this screen shows effect on advisory verification |
| Impacted decisions count | Security & Risk | Gate evaluation owner |
| Impact severity | Security & Risk | Risk scoring owner |
| Conflict detection / conflict diagnostics | Security & Risk | Conflict resolution belongs to security decision model |
| Unsigned advisory ratio | Security & Risk | Advisory interpretation owner |
- Page title:
Advisory Sources - Scope filters: region, environment, source family (feed type), freshness severity.
- Quick stats bar: total sources, healthy count, stale count, unavailable count.
- Healthy sources — count with trend.
- Stale sources — count with worst freshness age and SLA breach delta.
- Unavailable sources — count; includes sources with connectivity failure or mirror lag > threshold.
- Conflicting-source warnings — count of active advisory conflicts with unresolved triage status.
Required columns:
| Column | Source | Notes |
|---|
| Source name | Integrations | Link to Integrations connector detail with preserved source id |
| Source family | Integrations | Feed type (NVD, OSV, GHSA, vendor, custom) |
| Last successful ingest | Platform Ops | Timestamp |
| Freshness age | Platform Ops | Age since last successful ingest |
| Freshness SLA | Platform Ops | Configured SLA threshold |
| Freshness status | Platform Ops | Healthy / Warning / Stale / Unavailable badge |
| Signature / trust status | Administration | Signed / Unsigned / Untrusted |
| Impacted decisions count | Security & Risk | Count of release/approval decisions gated by this source |
| Impact severity | Security & Risk | Highest severity of active advisory in this source affecting decisions |
- Open connector config → navigates to Integrations connector detail (preserved source id).
- Open mirror ops → navigates to Platform Ops feeds/freshness page (preserved source id).
- View impacted findings/gates → navigates to Security & Risk findings filtered by source.
Opened from row click. Sections:
- Source status timeline — ingest events, gaps, and failure events.
- Conflict diagnostics — conflicting statement list with source pair, advisory id, conflict type (severity mismatch, remediation mismatch, existence conflict).
- Advisory statistics — total advisories, signed count, unsigned count, signature failure count.
- Impacted release/approval/environment references — linked list of active decisions impacted by this source.
| State | Trigger | UI treatment |
|---|
| Healthy | Freshness within SLA, signature valid or source is unsigned-accepted | Green badge; no action surfaced |
| Warning | Freshness age approaching SLA (configurable threshold, default 80%) | Yellow badge; show time-to-breach |
| Stale | Freshness age exceeds SLA | Red badge; show gating confidence degraded warning; show Open mirror ops action |
| Unavailable | No ingest activity in critical window or mirror failure | Critical badge; show Open connector config action; impacted decisions show degraded confidence |
| Conflicting | Active unresolved advisory conflict involving this source | Conflict badge; show conflict count; triage link |
| State | Trigger | UI treatment |
|---|
| All healthy | All sources healthy or warning | No banner; summary cards show normal |
| Degraded sources present | One or more stale or unavailable | Warning banner with count and quick action links |
| Conflict active | One or more unresolved conflicts | Security banner with conflict count; link to filtered view |
| Stale data | Advisory source API returns cached or stale data (> configured page-stale threshold) | Stale-data banner with last-refreshed timestamp; disable gating-critical actions |
| Hard fail | Advisory source API unavailable | Error banner; page content unavailable; link to Platform Ops data-integrity page |
| Empty | No advisory sources configured | Empty state with link to Integrations to configure first source |
- This page must not expose connector credential editing (Integrations owns this).
- This page must not expose freshness operation controls such as trigger sync, clear cache (Platform Ops owns this).
- This page must not host trust key or issuer management (Administration owns this).
- Conflict diagnostics is a read-only view; resolution actions are surfaced as links to owning triage surfaces.
| API | Proposed endpoint | Owner module | Status class | Auth scope | Notes |
|---|
| Advisory source list with freshness | GET /api/v1/advisory-sources | Concelier | EXISTS_COMPAT | advisory:read | Implemented; requires tenant via X-StellaOps-TenantId or tenant_id claim |
| Advisory source freshness detail | GET /api/v1/advisory-sources/{id}/freshness | Concelier | EXISTS_COMPAT | advisory:read | Implemented; supports source UUID/key lookup and includes advisory stats fields for detail diagnostics |
| Advisory source gating impact | GET /api/v1/advisory-sources/{id}/impact | Policy | EXISTS_COMPAT | findings:read | Implemented; supports region, environment, and sourceFamily filters |
| Advisory source conflict report | GET /api/v1/advisory-sources/{id}/conflicts | Policy | EXISTS_COMPAT | findings:read | Implemented; supports status plus deterministic limit/offset pagination |
| Advisory source summary aggregate | GET /api/v1/advisory-sources/summary | Concelier | EXISTS_COMPAT | advisory:read | Implemented card aggregate (healthy/warning/stale/unavailable/disabled/conflicts placeholder) |
| Security source freshness (existing) | GET /api/v1/security/sources/freshness (check Concelier) | Concelier | EXISTS_ADAPT | existing | May need freshness-SLA delta and impact-count additions |
- A single combined API that merges connector config and freshness without a clear split contract.
- Advisory Sources rendered as a sub-tab of Integrations or Platform Ops (Security & Risk is owner).
- Freshness operation controls embedded in this page (must be deep-link to Platform Ops only).