prep docs and service updates
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
# Excititor Consensus Removal Runbook (AOC-19-004)
|
||||
|
||||
- **Date:** 2025-11-21
|
||||
- **Scope:** EXCITITOR-CORE-AOC-19-004
|
||||
- **Goal:** Eliminate legacy consensus/merged severity fields so Excititor remains aggregation-only.
|
||||
|
||||
## Cutover steps
|
||||
1) **Freeze consensus refresh** — `DisableConsensus=true` (default) forces refresh loop off. Keep this enabled during migration.
|
||||
2) **Schema cleanup** — migrate collections to remove or null legacy fields:
|
||||
- `vex_consensus` / `vex_consensus_holds`: drop/ignore fields `consensusDigest`, `policyVersion`, `policyRevisionId`, `policyDigest`, `summary`, `signals`, `status` (merged) once Policy takes over.
|
||||
- `vex_observations` / materialized exports: ensure no merged severity/status fields are written.
|
||||
- `vex_mirror` exports: stop emitting consensus JSON; retain raw observations only.
|
||||
3) **Telemetry:** emit counter `excititor.ingest.consensus.disabled` (tags `tenant`, `source`, `connectorId`) once per batch to prove cutover.
|
||||
4) **Guards:** AOC guards reject any incoming/derived field in `{mergedSeverity, consensusScore, computedStatus}`.
|
||||
5) **Backfill:** run one-off job to set `consensusDisabled=true` on legacy records and remove merged fields without touching raw observations.
|
||||
6) **Verification:** regression checklist (per tenant):
|
||||
- No writes to `vex_consensus*` collections after cutover.
|
||||
- Ingest + export fixtures show only raw observations/linksets; snapshots deterministic.
|
||||
- Telemetry counter present; absence of consensus refresh logs.
|
||||
|
||||
## Config
|
||||
```
|
||||
Excititor:Worker:
|
||||
DisableConsensus: true # keep true post-cutover
|
||||
```
|
||||
|
||||
## Test plan (after disk space is restored)
|
||||
- Unit: AOC guard rejects merged fields.
|
||||
- Integration (Mongo2Go): ingest batch containing merged fields → rejected; telemetry counter increments.
|
||||
- Worker: start with DisableConsensus=true → consensus refresh loop does not schedule; log once at startup.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Excititor · Graph Linkouts & Overlays — Implementation Notes (Graph 21-001/002/005)
|
||||
|
||||
- **Date:** 2025-11-21
|
||||
- **Scope:** EXCITITOR-GRAPH-21-001, EXCITITOR-GRAPH-21-002, EXCITITOR-GRAPH-21-005
|
||||
- **Status:** Implementation guidance (storage wiring pending).
|
||||
|
||||
## Endpoints
|
||||
1) **Linkouts (21-001)**
|
||||
- `POST /internal/graph/linkouts`
|
||||
- Body: `tenant`, `purls[]` (max 500), `includeJustifications?`, `includeProvenance?`
|
||||
- Response: ordered by input `purls`; each item includes `advisories[]` (`advisoryId`, `source`, `status`, `justification?`, `modifiedAt`, `evidenceHash`, `connectorId`, `dsseEnvelopeHash?`) plus `conflicts[]`; `notFound[]`.
|
||||
|
||||
2) **Overlays (21-002)**
|
||||
- `GET /v1/graph/overlays?purl=<purl>&purl=<purl>&includeJustifications=true|false`
|
||||
- Response per PURL: `summary` counts (`open`, `not_affected`, `under_investigation`, `no_statement`), `latestModifiedAt`, `justifications[]` (unique, sorted), `provenance` (`sources[]`, `lastEvidenceHash`), `cached`, `cacheAgeMs`.
|
||||
|
||||
## Storage & Indexes (21-005)
|
||||
- `vex_observations` indexes:
|
||||
- `{ tenant: 1, component.purl: 1, advisoryId: 1, source: 1, modifiedAt: -1 }`
|
||||
- Sparse `{ tenant: 1, component.purl: 1, status: 1 }`
|
||||
- Optional materialized `vex_overlays` cache: unique `{ tenant: 1, purl: 1 }`, TTL on `cachedAt` driven by `excititor:graph:overlayTtlSeconds` (default 300s).
|
||||
|
||||
## Determinism
|
||||
- Ordering: input PURL order → `advisoryId` → `source` for linkouts; overlays follow input order.
|
||||
- Truncation: max 200 advisories per PURL; when truncated, include `truncated: true` and `nextCursor` (`advisoryId`, `source`).
|
||||
|
||||
## Config knobs
|
||||
- `excititor:graph:overlayTtlSeconds` (default 300)
|
||||
- `excititor:graph:maxPurls` (default 500)
|
||||
- `excititor:graph:maxAdvisoriesPerPurl` (default 200)
|
||||
|
||||
## Telemetry
|
||||
- Counter `excititor.graph.linkouts.requests` tags: `tenant`, `includeJustifications`, `includeProvenance`.
|
||||
- Counter `excititor.graph.overlays.cache` tags: `tenant`, `hit` (`true|false`).
|
||||
- Histogram `excititor.graph.linkouts.latency.ms` tags: `tenant`.
|
||||
|
||||
## Steps to implement
|
||||
- Bind `GraphOptions` to `Excititor:Graph`.
|
||||
- Add endpoints to WebService with tenant guard; enforce limits.
|
||||
- Implement overlay cache with deterministic sort; respect TTL; surface `cached` + `cacheAgeMs`.
|
||||
- Backfill Mongo indexes above.
|
||||
- Integration tests (WebApplicationFactory + Mongo2Go) for ordering, truncation, cache metadata, tenant isolation.
|
||||
39
docs/modules/excititor/operations/tenant-authority-client.md
Normal file
39
docs/modules/excititor/operations/tenant-authority-client.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Excititor Tenant Authority Client (AOC-19-013)
|
||||
|
||||
- **Date:** 2025-11-21
|
||||
- **Scope:** EXCITITOR-CORE-AOC-19-013
|
||||
- **Files:** `src/Excititor/StellaOps.Excititor.Worker/Auth/TenantAuthorityClientFactory.cs`
|
||||
|
||||
## Contract
|
||||
- Every outbound Authority call must carry `X-Tenant` header and use tenant-specific base URL.
|
||||
- Base URLs and optional client credentials are configured under `Excititor:Authority:` with per-tenant keys.
|
||||
- Factory throws when tenant is missing or not configured to prevent cross-tenant leakage.
|
||||
|
||||
## Configuration shape
|
||||
```json
|
||||
{
|
||||
"Excititor": {
|
||||
"Authority": {
|
||||
"BaseUrls": {
|
||||
"alpha": "https://authority.alpha.local/",
|
||||
"bravo": "https://authority.bravo.local/"
|
||||
},
|
||||
"ClientIds": {
|
||||
"alpha": "alpha-client-id"
|
||||
},
|
||||
"ClientSecrets": {
|
||||
"alpha": "alpha-secret"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Implementation notes
|
||||
- `TenantAuthorityClientFactory` (worker) enforces tenant presence and configured base URL; adds `Accept: application/json` and `X-Tenant` headers.
|
||||
- Registered in DI via `Program.cs` with options binding to `Excititor:Authority`.
|
||||
- Intended to be reused by WebService/Worker components once disk space block is resolved.
|
||||
|
||||
## Next steps
|
||||
- Wire factory into services that call Authority (WebService + Worker jobs), replacing any tenant-agnostic HttpClient usages.
|
||||
- Add integration tests to ensure cross-tenant calls reject when config missing or header mismatched.
|
||||
Reference in New Issue
Block a user