# Sprint 123 - Ingestion & Evidence · 110.C) Excititor.V Active items only. Completed/historic work now resides in docs/implplan/archived/tasks.md (updated 2025-11-08). [Ingestion & Evidence] 110.C) Excititor.V Depends on: Sprint 110.C - Excititor.IV Summary: Ingestion & Evidence focus on Excititor (phase V). > **Prep:** Read `docs/modules/excititor/architecture.md` and the Excititor component `AGENTS.md` files before touching this sprint’s tasks. Task ID | State | Task description | Owners (Source) --- | --- | --- | --- EXCITITOR-VEXLENS-30-001 `VEX evidence enrichers` | DONE | Ensure every observation exported to VEX Lens carries issuer hints, signature blobs, product tree snippets, and staleness metadata so the lens can compute consensus without calling back into Excititor. **Completed:** Enhanced `OpenVexSourceEntry` with enrichment fields (issuerHint, signatureType, keyId, transparencyLogRef, trustWeight, trustTier, stalenessSeconds, productTreeSnippet). Updated `OpenVexStatementMerger.BuildSources()` to extract from VexClaim. Enhanced `OpenVexExportSource` JSON serialization. | Excititor WebService Guild, VEX Lens Guild (src/Excititor/StellaOps.Excititor.WebService) EXCITITOR-VULN-29-001 `VEX key canonicalization` | DONE | Canonicalize advisory/product keys (map to `advisory_key`, capture scope metadata) while preserving original identifiers in `links[]`; run backfill + regression tests. **Completed:** Created `VexAdvisoryKeyCanonicalizer` (CVE/GHSA/RHSA/DSA/USN) and `VexProductKeyCanonicalizer` (PURL/CPE/RPM/DEB/OCI) in `Core/Canonicalization/`. All 47 tests passing. Supports extracting PURLs/CPEs from component identifiers. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService) EXCITITOR-VULN-29-002 `Evidence retrieval APIs` | DONE | Provide `/vuln/evidence/vex/{advisory_key}` returning tenant-scoped raw statements, provenance, and attestation references for Vuln Explorer evidence tabs. Depends on EXCITITOR-VULN-29-001. **Completed:** Created endpoint at `/vuln/evidence/vex/{advisory_key}` in `EvidenceEndpoints.cs`. Uses `VexAdvisoryKeyCanonicalizer` for key normalization (CVE, GHSA, RHSA, DSA, USN). Returns canonical key, scope, aliases, and statements with provenance (documentDigest, format, sourceUri, revision) and attestation metadata (signatureType, issuer, subject, keyId, verifiedAt, transparencyLogRef, trustWeight, trustTier). Supports cursor-based pagination. | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService) EXCITITOR-VULN-29-004 `Observability` | DONE | Add metrics/logs for normalization errors, suppression scopes, withdrawn statements, and feed them to Vuln Explorer + Advisory AI dashboards. Depends on EXCITITOR-VULN-29-002. **Completed:** Created `NormalizationTelemetry.cs` with comprehensive metrics: advisory/product key canonicalization (success/error counters, scope distribution), evidence retrieval (request counts, statement count histogram, latency histogram), normalization errors by provider/type, suppression scope tracking, withdrawn statement detection/replacements. Registered meter in `TelemetryExtensions.cs`. Added telemetry calls to evidence endpoint. | Excititor WebService Guild, Observability Guild (src/Excititor/StellaOps.Excititor.WebService) EXCITITOR-STORE-AOC-19-001 `vex_raw schema validator` | DONE | Ship Mongo JSON Schema + validator tooling (including Offline Kit instructions) so operators can prove Excititor stores only immutable evidence. **Completed:** Created `VexRawSchemaValidator` in `Storage.Mongo/Validation/` with `Validate()`, `ValidateBatch()`, `GetJsonSchema()` methods. Added Offline Kit docs at `docs/airgap/vex-raw-schema-validation.md`. | Excititor Storage Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo) EXCITITOR-STORE-AOC-19-002 `Idempotency index & migration` | DONE | Create unique indexes, run migrations/backfills, and document rollback steps for the new schema validator. Depends on EXCITITOR-STORE-AOC-19-001. **Completed:** Created `VexRawIdempotencyIndexMigration` with unique indexes (provider+source+digest), query indexes (digest+provider), and time-based index. Added rollback docs at `docs/airgap/vex-raw-migration-rollback.md`. Registered migration in ServiceCollectionExtensions. | Excititor Storage Guild, DevOps Guild (src/Excititor/__Libraries/StellaOps.Excititor.Storage.Mongo) EXCITITOR-AIRGAP-56-001 `Mirror registration APIs` | DONE | Support mirror bundle registration + provenance exposure, including sealed-mode error mapping and staleness metrics surfaced via API responses. **Completed:** Added query methods to `IAirgapImportStore` (ListAsync, FindByBundleIdAsync, CountAsync). Created `AirgapMirrorContracts.cs` with response types for bundle listing/detail/timeline and `AirgapErrorMapping` for structured sealed-mode errors with categories (validation, sealed_mode, trust, duplicate, not_found). Created `MirrorRegistrationEndpoints.cs` with `/airgap/v1/mirror/bundles` endpoints for listing, detail with provenance, and timeline queries. Added `StalenessCalculator` for computing staleness metrics with age categories (fresh, recent, stale, old, very_old). | Excititor WebService Guild (src/Excititor/StellaOps.Excititor.WebService) EXCITITOR-AIRGAP-58-001 `Portable evidence bundles` | DONE | Produce portable evidence bundles linked to timeline + attestation metadata for sealed deployments, and document verifier steps for Advisory AI teams. Depends on EXCITITOR-AIRGAP-56-001. **Completed:** Created `PortableEvidenceBundleBuilder` in `Core/Evidence/` with ZIP bundle creation including: manifest.json (VexLockerManifest with Merkle root), attestation.json (DSSE envelope), evidence items by provider, timeline.json (audit trail), bundle-manifest.json (content index), VERIFY.md (inline verification guide). Added comprehensive verification docs at `docs/airgap/portable-evidence-bundle-verification.md` with Python/Bash scripts for Merkle root verification, attestation checking, timeline validation, and Advisory AI integration patterns. | Excititor Core Guild, Evidence Locker Guild (src/Excititor/__Libraries/StellaOps.Excititor.Core)