Update docs, sprint plans, and compose configuration
Add 12 new sprint files (Integrations, Graph, JobEngine, FE, Router, AdvisoryAI), archive completed scheduler UI sprint, update module architecture docs (router, graph, jobengine, web, integrations), and add Gitea entrypoint script for local dev. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -36,6 +36,18 @@ docker compose -f ops/advisory-ai/docker-compose.advisoryai.yaml up -d --build
|
||||
- Compose mounts `advisoryai-data` volume; Helm uses `emptyDir` by default or a PVC when `storage.persistence.enabled=true`.
|
||||
- In sealed/air-gapped mode, mount guardrail lists/policy knobs under `/app/etc` and point env vars accordingly.
|
||||
|
||||
## PostgreSQL attribution and pooling
|
||||
- AdvisoryAI knowledge-search and unified-search PostgreSQL traffic now uses a shared pooled `NpgsqlDataSource` instead of per-operation transient data sources or raw connections.
|
||||
- Default `application_name` is `stellaops-advisory-ai-web/knowledge-search`, which makes `pg_stat_activity` attribution stable for the web service.
|
||||
- Default idle-pool retention is `900` seconds so the shared pool stays warm across the 5-minute unified-search refresh cycle instead of re-opening physical sessions each run.
|
||||
- Override these with:
|
||||
- `ADVISORYAI__KnowledgeSearch__DatabaseApplicationName`
|
||||
- `ADVISORYAI__KnowledgeSearch__DatabasePoolingEnabled`
|
||||
- `ADVISORYAI__KnowledgeSearch__DatabaseMinPoolSize`
|
||||
- `ADVISORYAI__KnowledgeSearch__DatabaseMaxPoolSize`
|
||||
- `ADVISORYAI__KnowledgeSearch__DatabaseConnectionIdleLifetimeSeconds`
|
||||
- Existing `ADVISORYAI__KnowledgeSearch__ConnectionString` remains authoritative for host/database/credentials; the new options only stamp attribution and pool behavior.
|
||||
|
||||
## Scaling guidance
|
||||
- WebService: start with 1 replica, scale horizontally by CPU (tokenization) or queue depth; set `ADVISORYAI__QUEUE__DIRECTORYPATH` to a shared PVC for multi-replica web+worker.
|
||||
- Worker: scale independently; use `worker.replicas` in Helm or add `--scale advisoryai-worker=N` in compose. Workers are CPU-bound; pin via `resources.requests/limits`.
|
||||
|
||||
@@ -37,6 +37,69 @@ Available for all commands:
|
||||
|
||||
---
|
||||
|
||||
## Integration Catalog Commands
|
||||
|
||||
### stella config integrations
|
||||
|
||||
Manage the live Integration Catalog through the Integrations service.
|
||||
|
||||
**Usage:**
|
||||
```bash
|
||||
stella config integrations <command> [options]
|
||||
```
|
||||
|
||||
**Subcommands:**
|
||||
- `list` - List catalog entries with filtering and paging
|
||||
- `providers` - List supported providers and discovery metadata
|
||||
- `get` / `show` - Display a single integration
|
||||
- `create` - Create an integration entry
|
||||
- `update` - Update an integration entry
|
||||
- `delete` / `remove` - Delete an integration entry
|
||||
- `test` - Run connector connectivity test
|
||||
- `health` - Query connector health
|
||||
- `impact` - Show workflow impact summary
|
||||
- `discover` - Discover provider resources such as repositories, projects, jobs, pipelines, or tags
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Show live providers (default hides test-only providers)
|
||||
stella config integrations providers
|
||||
|
||||
# Include test-only providers such as InMemory
|
||||
stella config integrations providers --include-test-only --format json
|
||||
|
||||
# Create a GitLab server entry
|
||||
stella config integrations create \
|
||||
--name local-gitlab \
|
||||
--type scm \
|
||||
--provider gitlabserver \
|
||||
--endpoint http://gitlab.stella-ops.local:8929 \
|
||||
--authref authref://vault/gitlab#access-token
|
||||
|
||||
# Discover projects from an existing integration
|
||||
stella config integrations discover <integration-id> --resource-type projects
|
||||
|
||||
# Discover tags within a repository
|
||||
stella config integrations discover <integration-id> \
|
||||
--resource-type tags \
|
||||
--filter repository=team/api \
|
||||
--filter namePattern='v*'
|
||||
|
||||
# Register local MinIO through the object-storage provider
|
||||
stella config integrations create \
|
||||
--name local-minio \
|
||||
--type objectstorage \
|
||||
--provider s3compatible \
|
||||
--endpoint http://minio.stella-ops.local:9000
|
||||
```
|
||||
|
||||
**Notes:**
|
||||
- `providers` returns `isTestOnly`, `supportsDiscovery`, and `supportedResourceTypes`.
|
||||
- Deprecated `stella integrations *` routes are preserved as aliases and forward to `stella config integrations *`.
|
||||
- Unsupported discovery requests return a client error instead of silently falling back to sample data.
|
||||
|
||||
---
|
||||
|
||||
## Scanning & Analysis Commands
|
||||
|
||||
### stella scan
|
||||
|
||||
@@ -26,6 +26,13 @@ Previously archived docs for RiskEngine and VulnExplorer are in `docs-archived/m
|
||||
- Merkle & external anchor policy: `merkle-anchor-policy.md`
|
||||
- Tenant isolation & redaction manifest: `tenant-isolation-redaction.md`
|
||||
|
||||
## Compatibility read-model surfaces
|
||||
|
||||
- `GET /api/v2/security/vulnerabilities/{identifier}` is the authoritative shipped vulnerability-detail route for the Web console.
|
||||
- The route is backed by Findings Ledger projections plus optional scoring state. Unknown fields remain null or absent instead of being fabricated in the API or the web client.
|
||||
- `signedScore` is emitted only when cached or historical scoring state exists for the resolved finding.
|
||||
- `proofSubjectId` is surfaced only when the projection carries replay/proof identity, allowing the Web console to enable verification only when a real proof subject exists.
|
||||
|
||||
## Implementation Status
|
||||
|
||||
### Delivery Phases
|
||||
|
||||
@@ -31,6 +31,13 @@
|
||||
- `POST /graph/diff` — compares `snapshotA` vs `snapshotB`, streaming node/edge added/removed/changed tiles plus stats; budget enforcement mirrors `/graph/query`.
|
||||
- `POST /graph/export` — async job producing deterministic manifests (`sha256`, size, format) for `ndjson/csv/graphml/png/svg`; download via `/graph/export/{jobId}`.
|
||||
- `POST /graph/lineage` - returns SBOM lineage nodes/edges anchored by `artifactDigest` or `sbomDigest`, with optional relationship filters and depth limits.
|
||||
- Compatibility facade for the shipped Angular explorer:
|
||||
- `GET /graphs`, `GET /graphs/{graphId}`, `GET /graphs/{graphId}/tiles`
|
||||
- `GET /search`, `GET /paths`
|
||||
- `GET /graphs/{graphId}/export`, `GET /assets/{assetId}/snapshot`, `GET /nodes/{nodeId}/adjacency`
|
||||
- `GET/POST/DELETE /graphs/{graphId}/saved-views`
|
||||
- The compatibility tile surface emits only `policy`, `vex`, and `aoc` overlays on the shipped web path.
|
||||
- Saved views are persisted in PostgreSQL table `graph.saved_views` when `Postgres:Graph` is configured; the API falls back to an in-memory store only for hosts that do not wire Graph persistence.
|
||||
- **Edge Metadata API** (added 2025-01):
|
||||
- `POST /graph/edges/metadata` — batch query for edge explanations; request contains `EdgeIds[]`, response includes `EdgeTileWithMetadata[]` with full provenance.
|
||||
- `GET /graph/edges/{edgeId}/metadata` — single edge metadata with explanation, via, provenance, and evidence references.
|
||||
@@ -77,6 +84,7 @@ The edge metadata system provides explainability for graph relationships:
|
||||
- **Relational + adjacency** (PostgreSQL tables `graph_nodes`, `graph_edges`, `graph_overlays`) with deterministic ordering and streaming exports.
|
||||
- Or **Graph DB** (e.g., Neo4j/Cosmos Gremlin) behind an abstraction layer; choice depends on deployment footprint.
|
||||
- All storages require tenant partitioning, append-only change logs, and export manifests for Offline Kits.
|
||||
- The shipped compatibility saved-view surface now owns a small relational persistence slice via startup migration `003_saved_views.sql`, which auto-creates `graph.saved_views` and keeps saved views durable across host restarts.
|
||||
|
||||
## 5) Offline & export
|
||||
|
||||
|
||||
@@ -123,10 +123,16 @@ The `CircuitBreakerService` implements the circuit breaker pattern for downstrea
|
||||
- `GET /api/v1/release-orchestrator/dashboard` — control-plane dashboard payload (pipeline, pending approvals, active deployments, recent releases).
|
||||
- `POST /api/v1/release-orchestrator/promotions/{id}/approve` — approve a pending promotion from dashboard context.
|
||||
- `POST /api/v1/release-orchestrator/promotions/{id}/reject` — reject a pending promotion from dashboard context.
|
||||
- `GET /api/v1/release-orchestrator/deployments` plus detail/log/event/metric endpoints and lifecycle actions (`pause`, `resume`, `cancel`, `rollback`, target `retry`) provide the release deployment monitoring surface used by the Console.
|
||||
- `POST /api/v1/release-orchestrator/deployments` creates a live deployment run for a single target environment using canonical strategies `rolling | blue_green | canary | all_at_once`.
|
||||
- `GET /api/v1/release-orchestrator/deployments` plus detail/log/event/metric endpoints and lifecycle actions (`pause`, `resume`, `cancel`, `rollback`, target `retry`) provide the release deployment monitoring surface used by the Console. The compatibility implementation is backed by persisted state in `orchestrator.compatibility_deployments`, with seed rows inserted per tenant only as bootstrap data.
|
||||
- `GET /api/v1/release-orchestrator/evidence` plus `verify`, `export`, `raw`, and `timeline` routes provide deterministic evidence inspection and export for offline audit flows.
|
||||
- Compatibility aliases are exposed for legacy clients under `/api/release-orchestrator/*`.
|
||||
|
||||
Compatibility deployment persistence notes:
|
||||
- Startup migration `011_compatibility_deployments.sql` creates the compatibility deployment table automatically as part of the normal JobEngine migration host.
|
||||
- The WebService resolves `IDeploymentCompatibilityStore` through DI: PostgreSQL when JobEngine persistence is configured, in-memory fallback otherwise.
|
||||
- Configuration precedence is explicit: `JobEngine:Database:ConnectionString` wins when provided, while legacy `Orchestrator:Database:ConnectionString` remains a fallback for hosts that have not yet moved to the JobEngine section.
|
||||
|
||||
All responses include deterministic timestamps, job digests, and DSSE signature fields for offline reconciliation.
|
||||
|
||||
## 5) Observability
|
||||
|
||||
@@ -219,6 +219,43 @@ const gitlabToken: CredentialReference = {
|
||||
};
|
||||
```
|
||||
|
||||
## Live Catalog Workflow
|
||||
|
||||
The shipped operator workflow is now backed by the Integrations service rather than CLI sample data.
|
||||
|
||||
### Provider Discovery
|
||||
|
||||
- `GET /api/v1/integrations/providers` returns live provider metadata from the loaded connector plugins.
|
||||
- Default responses hide test-only providers such as `InMemory`.
|
||||
- Each provider entry now advertises:
|
||||
- `isTestOnly`
|
||||
- `supportsDiscovery`
|
||||
- `supportedResourceTypes`
|
||||
|
||||
### Resource Discovery
|
||||
|
||||
- `POST /api/v1/integrations/{id}/discover` is the supported discovery contract.
|
||||
- Registry providers discover `repositories` and `tags`.
|
||||
- SCM providers discover `projects` and `repositories`.
|
||||
- CI/CD providers discover `jobs` and `pipelines`.
|
||||
- Object storage providers such as `S3Compatible` participate in the live catalog and health/test flows, but do not currently advertise discovery.
|
||||
- Unsupported resource types return `400` with the provider's supported resource types.
|
||||
|
||||
### CLI Management Surface
|
||||
|
||||
The `stella config integrations` command group manages the live catalog end-to-end:
|
||||
|
||||
```bash
|
||||
stella config integrations providers
|
||||
stella config integrations list
|
||||
stella config integrations create --name local-gitlab --type scm --provider gitlabserver --endpoint http://gitlab.stella-ops.local:8929 --authref authref://vault/gitlab#access-token
|
||||
stella config integrations create --name local-minio --type objectstorage --provider s3compatible --endpoint http://minio.stella-ops.local:9000
|
||||
stella config integrations test <integration-id>
|
||||
stella config integrations discover <integration-id> --resource-type projects
|
||||
```
|
||||
|
||||
Deprecated `stella integrations *` routes are preserved as aliases and forward to `stella config integrations *`.
|
||||
|
||||
## Health Monitoring
|
||||
|
||||
### Health Check Types
|
||||
|
||||
@@ -24,7 +24,7 @@ Rollout policy: `docs/operations/multi-tenant-rollout-and-compatibility.md`
|
||||
|
||||
Each transport connection carries:
|
||||
|
||||
- Initial registration (HELLO) and endpoint configuration
|
||||
- Initial identity (HELLO) and, when needed, endpoint metadata replay
|
||||
- Ongoing heartbeats
|
||||
- Request/response data frames
|
||||
- Streaming data frames
|
||||
@@ -34,9 +34,11 @@ Each transport connection carries:
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Microservice │ │ Gateway │
|
||||
│ │ HELLO │ │
|
||||
│ Endpoints: │ ─────────────────────────►│ Routing │
|
||||
│ Identity │ ─────────────────────────►│ Routing │
|
||||
│ - POST /items │ HEARTBEAT │ State │
|
||||
│ - GET /items │ ◄────────────────────────►│ │
|
||||
│ Metadata │ RESYNC / ENDPOINTS │ Connections[] │
|
||||
│ replay │ ◄────────────────────────►│ │
|
||||
│ │ │ Connections[] │
|
||||
│ │ REQUEST / RESPONSE │ │
|
||||
│ │ ◄────────────────────────►│ │
|
||||
@@ -280,7 +282,9 @@ public enum FrameType : byte
|
||||
Response = 4,
|
||||
RequestStreamData = 5,
|
||||
ResponseStreamData = 6,
|
||||
Cancel = 7
|
||||
Cancel = 7,
|
||||
ResyncRequest = 8,
|
||||
EndpointsUpdate = 9
|
||||
}
|
||||
```
|
||||
|
||||
@@ -415,9 +419,10 @@ Two mechanisms:
|
||||
### Connection Behavior
|
||||
|
||||
On connection:
|
||||
1. Send HELLO with instance info and endpoints
|
||||
2. Start heartbeat timer
|
||||
3. Listen for REQUEST frames
|
||||
1. Send HELLO with instance identity.
|
||||
2. Start heartbeat timer.
|
||||
3. For messaging transport, replay endpoint/schema/OpenAPI metadata only when the router explicitly asks for it.
|
||||
4. Listen for REQUEST frames.
|
||||
|
||||
HELLO payload:
|
||||
|
||||
@@ -431,6 +436,11 @@ public sealed class HelloPayload
|
||||
}
|
||||
```
|
||||
|
||||
For messaging transport the steady-state contract is intentionally slimmer than the generic shape above:
|
||||
- startup `HELLO` carries identity and may leave `Endpoints` empty
|
||||
- the gateway sends `ResyncRequest` on service startup, administrative replay, or gateway-state miss
|
||||
- the microservice answers with `EndpointsUpdate` containing endpoints, schemas, and OpenAPI metadata
|
||||
|
||||
---
|
||||
|
||||
## Authorization
|
||||
@@ -449,7 +459,7 @@ public sealed class ClaimRequirement
|
||||
|
||||
### Precedence
|
||||
|
||||
1. Microservice provides defaults in HELLO
|
||||
1. Microservice provides defaults in registration metadata
|
||||
2. Authority can override centrally
|
||||
3. Gateway enforces final effective claims
|
||||
|
||||
@@ -533,9 +543,12 @@ Sent at regular intervals over the same connection as requests:
|
||||
```csharp
|
||||
public sealed class HeartbeatPayload
|
||||
{
|
||||
public InstanceDescriptor? Instance { get; init; }
|
||||
public string InstanceId { get; init; }
|
||||
public required InstanceHealthStatus Status { get; init; }
|
||||
public int InflightRequests { get; init; }
|
||||
public int InFlightRequestCount { get; init; }
|
||||
public double ErrorRate { get; init; }
|
||||
public DateTime TimestampUtc { get; init; }
|
||||
}
|
||||
```
|
||||
|
||||
@@ -546,13 +559,14 @@ Gateway tracks:
|
||||
- Derives status from heartbeat recency
|
||||
- Marks stale instances as Unhealthy
|
||||
- Uses health in routing decisions
|
||||
- Messaging heartbeats include instance identity so the gateway can rebuild minimal state after a gateway restart or local routing-state loss without waiting for a full reconnect.
|
||||
- Messaging transports stay push-first even when backed by notifiable queues; the missed-notification safety-net timeout is derived from the configured heartbeat interval and clamped to a short bounded window instead of falling back to a fixed long poll.
|
||||
- Gateway degraded and stale transitions are normalized against the messaging heartbeat contract. A gateway may not mark an instance `Degraded` earlier than `2x` the heartbeat interval or `Unhealthy` earlier than `3x` the heartbeat interval, even when looser defaults were configured.
|
||||
- `/health/ready` is stricter than "process started": it remains `503` until the configured required first-party microservices have live healthy or degraded registrations in router state. Local scratch compose uses this to hold the frontdoor unhealthy until the core Stella API surface has replayed HELLO after a rebuild.
|
||||
- The required-service list must use canonical router `serviceName` values, not loose product-family aliases. Gateway readiness normalizes host-style suffixes such as `-gateway`, `-web`, `.stella-ops.local`, and ports, but it does not treat sibling services as interchangeable.
|
||||
- When a request already matched a configured `Microservice` route but the target service has not registered yet, the gateway returns `503 Service Unavailable`, not `404 Not Found`. `404` remains reserved for genuinely unknown paths or missing endpoints on an otherwise registered service.
|
||||
|
||||
Periodic HELLO re-registration is valid so a microservice can repopulate gateway state after a gateway restart, but it must refresh the existing logical transport connection instead of minting a second one. Gateway routing state also deduplicates by service instance identity (`ServiceName`, `Version`, `InstanceId`, transport) before re-indexing endpoints so repeated HELLO frames cannot accumulate stale route candidates.
|
||||
- Messaging resync is explicit instead of periodic: startup, administrative replay, and gateway-state misses trigger `ResyncRequest`, while normal heartbeats stay small.
|
||||
- The Valkey transport keeps its timeout fallback plus proactive randomized re-subscribe so silent Pub/Sub failures still recover. That fallback still produces some `XREADGROUP`/`XAUTOCLAIM` traffic, but it is resilience traffic rather than endpoint-catalog churn.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
## Status
|
||||
- **Implemented** in Sprint 8100.0011.0003.
|
||||
- Core components: Gateway DI wiring, GatewayHostedService integration, GatewayTransportClient dispatch.
|
||||
- Last updated: 2025-12-24 (UTC).
|
||||
- Last updated: 2026-04-05 (UTC).
|
||||
|
||||
## Purpose
|
||||
Enable Gateway ↔ microservice Router traffic over an offline-friendly, Redis-compatible transport (Valkey) by using the existing **Messaging** transport layer:
|
||||
@@ -27,20 +27,28 @@ This supports environments where direct TCP/TLS microservice connections are und
|
||||
|
||||
## High-Level Flow
|
||||
1) Microservice connects via messaging transport:
|
||||
- publishes a HELLO message to the gateway request queue
|
||||
- publishes a slim `HELLO` message with instance identity to the gateway control queue
|
||||
2) Gateway processes HELLO:
|
||||
- registers instance + endpoints into routing state
|
||||
3) Gateway routes an HTTP request to a microservice:
|
||||
- registers the connection identity and requests endpoint metadata replay when needed
|
||||
3) Microservice answers the replay request:
|
||||
- publishes an `EndpointsUpdate` frame with endpoints, schemas, and OpenAPI metadata
|
||||
4) Gateway applies the metadata replay:
|
||||
- updates routing state, effective claims, and aggregated OpenAPI
|
||||
5) Gateway routes an HTTP request to a microservice:
|
||||
- publishes a REQUEST message to the service request queue
|
||||
4) Microservice handles request:
|
||||
6) Microservice handles request:
|
||||
- executes handler (or ASP.NET bridge) and publishes a RESPONSE message
|
||||
5) Gateway returns response to the client.
|
||||
7) Gateway returns response to the client.
|
||||
|
||||
Messaging-specific recovery behavior:
|
||||
- Startup resync: the gateway sends `ResyncRequest` immediately after a slim `HELLO`.
|
||||
- Administrative resync: `POST /api/v1/gateway/administration/router/resync` can request replay for one connection or the whole messaging fleet.
|
||||
- Gateway-state miss: if a heartbeat arrives for an unknown messaging connection, the gateway seeds minimal state from the heartbeat identity and requests replay instead of waiting for a reconnect.
|
||||
|
||||
## Queue Topology (Conceptual)
|
||||
The Messaging transport uses a small set of queues (names are configurable):
|
||||
- **Gateway request queue**: receives HELLO / HEARTBEAT / REQUEST frames from services
|
||||
- **Gateway response queue**: receives RESPONSE frames from services
|
||||
- **Per-service request queues**: gateway publishes REQUEST frames targeted to a service
|
||||
- **Gateway control queue**: receives service-to-gateway HELLO / HEARTBEAT / ENDPOINTS_UPDATE / RESPONSE frames
|
||||
- **Per-service incoming queues**: gateway publishes REQUEST / CANCEL / RESYNC_REQUEST frames targeted to a service
|
||||
- **Dead letter queues** (optional): for messages that exceed retries/leases
|
||||
|
||||
## Configuration
|
||||
@@ -87,6 +95,8 @@ if (bootstrapOptions.Transports.Messaging.Enabled)
|
||||
- **At-least-once** delivery: message queues and leases imply retries are possible; handlers should be idempotent where feasible.
|
||||
- **Lease timeouts**: must be tuned to max handler execution time; long-running tasks should respond with 202 + job id rather than blocking.
|
||||
- **Determinism**: message ordering may vary; Router must not depend on arrival order for correctness (only for freshness/telemetry).
|
||||
- **Push-first with recovery fallback**: Valkey Pub/Sub notifications wake consumers immediately when possible. If notifications silently stop, the queue layer still wakes via timeout fallback, connection-restored hooks, and randomized proactive re-subscription so requests and resync control frames do not wedge forever.
|
||||
- **Queue fallback cost**: every wake can perform `XAUTOCLAIM` plus `XREADGROUP` checks before sleeping again. That traffic is expected resilience overhead, but it is materially smaller than replaying the full endpoint catalog on every heartbeat interval.
|
||||
|
||||
## Security Notes
|
||||
- Messaging transport is internal. External identity must still be enforced at the Gateway.
|
||||
@@ -97,11 +107,12 @@ if (bootstrapOptions.Transports.Messaging.Enabled)
|
||||
|
||||
### Completed (Sprint 8100.0011.0003)
|
||||
1. ✅ Wire Messaging transport into Gateway:
|
||||
- start/stop `MessagingTransportServer` in `GatewayHostedService`
|
||||
- subscribe to `OnHelloReceived`, `OnHeartbeatReceived`, `OnResponseReceived`, `OnConnectionClosed` events
|
||||
- reuse routing state updates and claims store updates
|
||||
- start/stop `MessagingTransportServer` in `GatewayHostedService`
|
||||
- subscribe to `OnHelloReceived`, `OnHeartbeatReceived`, `OnEndpointsUpdated`, `OnResponseReceived`, `OnConnectionClosed` events
|
||||
- reuse routing state updates and claims store updates
|
||||
2. ✅ Extend Gateway transport client to support `TransportType.Messaging` for dispatch.
|
||||
3. ✅ Add config options (`GatewayMessagingTransportOptions`) and DI mappings.
|
||||
4. ✅ Switch messaging registration from periodic full HELLO replay to explicit `ResyncRequest` / `EndpointsUpdate` control frames.
|
||||
|
||||
### Remaining Work
|
||||
1. Add deployment examples (compose/helm) for Valkey transport.
|
||||
|
||||
@@ -219,16 +219,25 @@ Graph explorer overlay behavior now supports deterministic lattice-state reachab
|
||||
|
||||
Behavior details:
|
||||
|
||||
- Reachability legend in overlay controls maps lattice states `SR/SU/RO/RU/CR/CU/X` to explicit halo colors.
|
||||
- Time slider now binds to deterministic snapshot checkpoints (`current`, `1d`, `7d`, `30d`) and renders timeline event text for each selection.
|
||||
- Reachability mock data generation is deterministic per `(nodeId, snapshot)` so repeated runs produce stable lattice status, confidence, and observation timestamps.
|
||||
- Canvas halo stroke colors are derived from lattice state (not generic status), and halo titles include lattice state plus observed timestamp for operator audit context.
|
||||
- Overlay controls only expose the live shipped overlay families `policy`, `vex`, and `aoc`.
|
||||
- The explorer route consumes `GET /graphs/{graphId}/tiles?includeOverlays=true` through `GraphPlatformHttpClient`.
|
||||
- Canvas halo colors and summaries derive from live overlay payloads, with policy taking precedence over vex and aoc when multiple overlays exist for the same node.
|
||||
- When a graph has no overlays, the shipped route shows explicit empty-state messaging rather than inventing reachability or simulation data.
|
||||
|
||||
Verification coverage:
|
||||
|
||||
- `src/Web/StellaOps.Web/src/tests/graph_reachability_overlay/graph-overlays.component.spec.ts`
|
||||
- `src/Web/StellaOps.Web/src/tests/graph_reachability_overlay/graph-canvas.component.spec.ts`
|
||||
|
||||
### 3.8 Active-Surface Verification Lane and Setup Wizard Styling (Sprint 20260405_002 / 005)
|
||||
|
||||
Focused verification and bundle-polish notes for the shipped surfaces:
|
||||
|
||||
- The repo now carries a dedicated active-surface test lane: `ng run stellaops-web:test-active-surfaces` (also exposed as `npm run test:active-surfaces`).
|
||||
- The lane intentionally covers the currently shipped Graph, Evidence, deployment creation, vulnerability detail, and environment-detail flows instead of the broader legacy spec backlog.
|
||||
- The setup wizard and step-content styling moved from oversized inline component styles into global SCSS under `src/Web/StellaOps.Web/src/styles/` so the production build clears `anyComponentStyle` budgets without raising those budgets.
|
||||
- Touched shipped routes continue to use explicit live empty/error/unavailable states rather than mock action fallbacks.
|
||||
|
||||
---
|
||||
|
||||
## 4) Authentication
|
||||
|
||||
Reference in New Issue
Block a user