documentation cleanse, sprints work and planning. remaining non EF DAL migration to EF
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"tier": 1,
|
||||
"type": "code_review",
|
||||
"capturedAtUtc": "2026-02-12T00:00:00Z",
|
||||
"feature": "epss-feed-connector",
|
||||
"claimsVerified": true,
|
||||
"missingClaims": [],
|
||||
"presentClaims": [
|
||||
"EpssConnector exists at src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssConnector.cs",
|
||||
"EpssConnectorPlugin exists at src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssConnectorPlugin.cs"
|
||||
],
|
||||
"verdict": "done",
|
||||
"notes": "EPSS feed connector fully implemented with three-stage Fetch/Parse/Map pattern, plugin registration, and IFeedConnector implementation."
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"feature": "epss-feed-connector",
|
||||
"module": "concelier",
|
||||
"tier": 0,
|
||||
"runId": "run-002",
|
||||
"timestamp": "2026-02-13T01:20:00Z",
|
||||
"result": "pass",
|
||||
"sourceFiles": [
|
||||
{
|
||||
"path": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssConnector.cs",
|
||||
"lines": 797,
|
||||
"role": "IFeedConnector implementation: FetchAsync (HTTP+ETag+retry+airgap), ParseAsync (CSV gzip stream), MapAsync (EpssMapper.ToObservation)"
|
||||
},
|
||||
{
|
||||
"path": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssMapper.cs",
|
||||
"lines": 54,
|
||||
"role": "Band classification: Critical>=0.70, High>=0.40, Medium>=0.10, Low<0.10"
|
||||
},
|
||||
{
|
||||
"path": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssCursor.cs",
|
||||
"lines": 169,
|
||||
"role": "Cursor state: DocumentObject round-trip, pending document/mapping tracking, snapshot metadata, deterministic serialization"
|
||||
},
|
||||
{
|
||||
"path": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssDiagnostics.cs",
|
||||
"lines": 85,
|
||||
"role": "Meter instrumentation: fetch attempts/success/failure/unchanged, parse rows/failures, mapped rows"
|
||||
},
|
||||
{
|
||||
"path": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Configuration/EpssOptions.cs",
|
||||
"lines": 59,
|
||||
"role": "Configuration with Validate(): BaseUri, CatchUpDays, HttpTimeout, MaxRetries, UserAgent, AirgapMode+BundlePath"
|
||||
},
|
||||
{
|
||||
"path": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssConnectorPlugin.cs",
|
||||
"lines": 24,
|
||||
"role": "IConnectorPlugin: SourceName='epss', IsAvailable, Create via DI"
|
||||
},
|
||||
{
|
||||
"path": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Jobs.cs",
|
||||
"lines": 49,
|
||||
"role": "Three IJob implementations: EpssFetchJob, EpssParseJob, EpssMapJob"
|
||||
}
|
||||
],
|
||||
"notes": "Full three-stage IFeedConnector (Fetch/Parse/Map) with ETag conditional HTTP, air-gap bundle fallback, retry with exponential backoff, priority band classification, cursor state management, and OTel metrics."
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"feature": "epss-feed-connector",
|
||||
"module": "concelier",
|
||||
"tier": 1,
|
||||
"runId": "run-002",
|
||||
"timestamp": "2026-02-13T01:20:00Z",
|
||||
"result": "pass",
|
||||
"buildCommand": "dotnet test src\\Concelier\\__Tests\\StellaOps.Concelier.Connector.Epss.Tests\\StellaOps.Concelier.Connector.Epss.Tests.csproj --no-restore -v normal",
|
||||
"testProject": "StellaOps.Concelier.Connector.Epss.Tests",
|
||||
"total": 46,
|
||||
"passed": 46,
|
||||
"failed": 0,
|
||||
"skipped": 0,
|
||||
"duration": "554ms",
|
||||
"breakdown": {
|
||||
"existingTests": 24,
|
||||
"newTests": 22,
|
||||
"newTestFiles": [
|
||||
"Configuration/EpssOptionsValidationTests.cs (12 tests)",
|
||||
"Internal/EpssCursorRoundTripTests.cs (7 tests)",
|
||||
"EpssConnectorPluginTests.cs (3 tests)"
|
||||
]
|
||||
},
|
||||
"notes": "46/46 pass. 24 existing (6 connector E2E + 18 parser snapshot/band) + 22 new (12 options validation + 7 cursor round-trip + 3 plugin). Zero warnings, zero errors."
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"feature": "epss-feed-connector",
|
||||
"module": "concelier",
|
||||
"tier": 2,
|
||||
"runId": "run-002",
|
||||
"timestamp": "2026-02-13T01:20:00Z",
|
||||
"result": "pass",
|
||||
"targetedTests": [
|
||||
{
|
||||
"class": "EpssConnectorTests",
|
||||
"testCount": 6,
|
||||
"tests": [
|
||||
"FetchAsync_StoresDocument_OnSuccess",
|
||||
"FetchAsync_ReturnsNotModified_OnEtagMatch",
|
||||
"ParseAsync_CreatesDto_AndUpdatesStatus",
|
||||
"MapAsync_MarksDocumentMapped",
|
||||
"ToObservation_AssignsBand (Theory: 0.75=Critical, 0.55=High, 0.25=Medium, 0.05=Low)",
|
||||
"EpssCursor_Empty_UsesMinValue"
|
||||
],
|
||||
"assertions": "Full Fetch/Parse/Map pipeline: HTTP fetch stores document as PendingParse, ETag conditional 304 skips storage, Parse creates DTO and transitions to PendingMap, Map transitions to Mapped. Band classification verified at representative scores. Cursor empty state validated."
|
||||
},
|
||||
{
|
||||
"class": "EpssParserSnapshotTests",
|
||||
"testCount": 18,
|
||||
"tests": [
|
||||
"ParseTypicalCsv_ProducesExpectedObservations (golden-file snapshot)",
|
||||
"ParseEdgeExtremeValues_ProducesExpectedObservations (golden-file snapshot)",
|
||||
"ParseTypicalCsv_IsDeterministic (3-run JSON equality)",
|
||||
"ParseMissingHeader_HandlesGracefully (resilience)",
|
||||
"BandClassification_IsCorrect (Theory: 11 boundary cases at 0.99999/0.75/0.70/0.69999/0.50/0.40/0.39999/0.25/0.10/0.09999/0.00001)"
|
||||
],
|
||||
"assertions": "Snapshot tests verify CSV->observation determinism against golden files. Boundary-precise band classification at every threshold (Critical>=0.70, High>=0.40, Medium>=0.10, Low<0.10). Error resilience on missing headers."
|
||||
},
|
||||
{
|
||||
"class": "EpssOptionsValidationTests",
|
||||
"testCount": 12,
|
||||
"tests": [
|
||||
"Validate_DefaultOptions_DoesNotThrow",
|
||||
"Validate_NullBaseUri_Throws",
|
||||
"Validate_NegativeCatchUpDays_Throws",
|
||||
"Validate_ZeroHttpTimeout_Throws",
|
||||
"Validate_NegativeMaxRetries_Throws",
|
||||
"Validate_EmptyUserAgent_Throws",
|
||||
"Validate_AirgapMode_WithoutBundlePath_Throws",
|
||||
"Validate_AirgapMode_WithBundlePath_DoesNotThrow",
|
||||
"Validate_ZeroCatchUpDays_DoesNotThrow",
|
||||
"Validate_ZeroMaxRetries_DoesNotThrow",
|
||||
"SectionName_IsExpected",
|
||||
"HttpClientName_IsExpected"
|
||||
],
|
||||
"assertions": "NEW: All 6 Validate() branches tested (null BaseUri, negative CatchUpDays, zero timeout, negative retries, empty UserAgent, airgap without bundle). Boundary cases (zero CatchUpDays, zero retries, airgap with bundle). Constants verified.",
|
||||
"gap": "Previously untested"
|
||||
},
|
||||
{
|
||||
"class": "EpssCursorRoundTripTests",
|
||||
"testCount": 7,
|
||||
"tests": [
|
||||
"Empty_RoundTrips_ToEmpty",
|
||||
"FullCursor_RoundTrips_AllFields",
|
||||
"FromDocument_NullDocument_ReturnsEmpty",
|
||||
"WithPendingDocuments_DeduplicatesIds",
|
||||
"WithPendingMappings_DeduplicatesIds",
|
||||
"WithSnapshotMetadata_WhitespaceStrings_NormalizedToNull",
|
||||
"ToDocumentObject_SortsPendingCollections_ForDeterminism"
|
||||
],
|
||||
"assertions": "NEW: Full round-trip (ToDocumentObject -> FromDocument) for empty and full cursors. Deduplication of pending IDs. Whitespace normalization to null. Deterministic sorted serialization of GUID collections.",
|
||||
"gap": "Previously untested"
|
||||
},
|
||||
{
|
||||
"class": "EpssConnectorPluginTests",
|
||||
"testCount": 3,
|
||||
"tests": [
|
||||
"Name_ReturnsEpss",
|
||||
"IsAvailable_WithoutRegisteredConnector_ReturnsFalse",
|
||||
"Create_WithNullServices_ThrowsArgumentNull"
|
||||
],
|
||||
"assertions": "NEW: Plugin SourceName constant, IsAvailable returns false without DI registration, Create null guard.",
|
||||
"gap": "Previously untested"
|
||||
}
|
||||
],
|
||||
"notes": "46/46 tests pass. 24 existing cover the Fetch/Parse/Map pipeline, ETag conditional, golden-file snapshots, determinism, resilience, and boundary-precise band classification (11 boundary values). 22 NEW tests close gaps in EpssOptions.Validate() (all 6 branches), EpssCursor round-trip (full field preservation, deduplication, normalization, deterministic serialization), and EpssConnectorPlugin (name, availability, null guard)."
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"featureFile": "docs/features/unchecked/concelier/epss-feed-connector.md",
|
||||
"filesChecked": [
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssConnector.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssMapper.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssConnectorPlugin.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Configuration/EpssOptions.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssCursor.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssDiagnostics.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssDependencyInjectionRoutine.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssServiceCollectionExtensions.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Jobs.cs"
|
||||
],
|
||||
"found": [
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssConnector.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssMapper.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssConnectorPlugin.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Configuration/EpssOptions.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssCursor.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Internal/EpssDiagnostics.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssDependencyInjectionRoutine.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/EpssServiceCollectionExtensions.cs",
|
||||
"src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/Jobs.cs"
|
||||
],
|
||||
"missing": [],
|
||||
"verdict": "pass"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"project": "src/Concelier/__Libraries/StellaOps.Concelier.Connector.Epss/StellaOps.Concelier.Connector.Epss.csproj",
|
||||
"testProject": "src/Concelier/__Tests/StellaOps.Concelier.Connector.Epss.Tests/StellaOps.Concelier.Connector.Epss.Tests.csproj",
|
||||
"buildResult": "pass",
|
||||
"testResult": "pass",
|
||||
"totalTests": 46,
|
||||
"testsPassed": 46,
|
||||
"testsFailed": 0,
|
||||
"errors": [],
|
||||
"codeReviewChecklist": {
|
||||
"mainClassExists": true,
|
||||
"nonTrivialImplementation": true,
|
||||
"logicMatchesFeatureDescription": true,
|
||||
"unitTestsExerciseCoreBehavior": true,
|
||||
"testsAssertMeaningfulOutcomes": true
|
||||
},
|
||||
"codeReviewNotes": [
|
||||
"EpssConnector implements IFeedConnector with full three-stage Fetch/Parse/Map pattern (797 lines)",
|
||||
"EpssMapper.ToObservation maps EPSS scores to EpssObservation with DetermineBand classifying Critical>=0.70, High>=0.40, Medium>=0.10, Low<0.10",
|
||||
"EpssConnectorPlugin implements IConnectorPlugin for DI discovery with SourceName='epss'",
|
||||
"EpssOptions validates all config including AirgapMode requiring BundlePath",
|
||||
"EpssCursor handles deterministic serialization with sorted GUID collections and round-trip fidelity",
|
||||
"HTTP fetch supports ETag conditional requests (If-None-Match), 304 Not Modified handling, and retry with exponential backoff",
|
||||
"Air-gap bundle fallback reads from local file system with optional manifest verification (SHA-256 hash check)",
|
||||
"Tests verify: fetch stores document, ETag 304 handling, parse creates DTO, map marks document mapped, band classification at all thresholds, cursor round-trips, options validation"
|
||||
],
|
||||
"verdict": "pass"
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"type": "integration",
|
||||
"capturedAtUtc": "2026-02-12T23:20:00Z",
|
||||
"testCommand": "dotnet test \"src\\Concelier\\__Tests\\StellaOps.Concelier.Connector.Epss.Tests\\StellaOps.Concelier.Connector.Epss.Tests.csproj\" --no-restore -v normal",
|
||||
"testFilter": "all tests in dedicated .csproj",
|
||||
"testsRun": 46,
|
||||
"testsPassed": 46,
|
||||
"testsFailed": 0,
|
||||
"targetedTestMethods": [
|
||||
"EpssConnectorTests.FetchAsync_StoresDocument_OnSuccess",
|
||||
"EpssConnectorTests.FetchAsync_ReturnsNotModified_OnEtagMatch",
|
||||
"EpssConnectorTests.ParseAsync_CreatesDto_AndUpdatesStatus",
|
||||
"EpssConnectorTests.MapAsync_MarksDocumentMapped",
|
||||
"EpssConnectorTests.ToObservation_AssignsBand(score=0.75, expected=Critical)",
|
||||
"EpssConnectorTests.ToObservation_AssignsBand(score=0.55, expected=High)",
|
||||
"EpssConnectorTests.ToObservation_AssignsBand(score=0.25, expected=Medium)",
|
||||
"EpssConnectorTests.ToObservation_AssignsBand(score=0.05, expected=Low)",
|
||||
"EpssConnectorTests.EpssCursor_Empty_UsesMinValue",
|
||||
"EpssParserSnapshotTests.ParseTypicalCsv_ProducesExpectedObservations",
|
||||
"EpssParserSnapshotTests.ParseEdgeExtremeValues_ProducesExpectedObservations",
|
||||
"EpssParserSnapshotTests.ParseTypicalCsv_IsDeterministic",
|
||||
"EpssParserSnapshotTests.ParseMissingHeader_HandlesGracefully",
|
||||
"EpssParserSnapshotTests.BandClassification_IsCorrect(11 threshold cases)",
|
||||
"EpssConnectorPluginTests.Name_ReturnsEpss",
|
||||
"EpssConnectorPluginTests.IsAvailable_WithoutRegisteredConnector_ReturnsFalse",
|
||||
"EpssConnectorPluginTests.Create_WithNullServices_ThrowsArgumentNull",
|
||||
"EpssOptionsValidationTests.Validate_DefaultOptions_DoesNotThrow",
|
||||
"EpssOptionsValidationTests.Validate_NullBaseUri_Throws",
|
||||
"EpssOptionsValidationTests.Validate_NegativeCatchUpDays_Throws",
|
||||
"EpssOptionsValidationTests.Validate_ZeroHttpTimeout_Throws",
|
||||
"EpssOptionsValidationTests.Validate_NegativeMaxRetries_Throws",
|
||||
"EpssOptionsValidationTests.Validate_EmptyUserAgent_Throws",
|
||||
"EpssOptionsValidationTests.Validate_AirgapMode_WithoutBundlePath_Throws",
|
||||
"EpssOptionsValidationTests.Validate_AirgapMode_WithBundlePath_DoesNotThrow",
|
||||
"EpssOptionsValidationTests.Validate_ZeroCatchUpDays_DoesNotThrow",
|
||||
"EpssOptionsValidationTests.Validate_ZeroMaxRetries_DoesNotThrow",
|
||||
"EpssOptionsValidationTests.SectionName_IsExpected",
|
||||
"EpssOptionsValidationTests.HttpClientName_IsExpected",
|
||||
"EpssCursorRoundTripTests.Empty_RoundTrips_ToEmpty",
|
||||
"EpssCursorRoundTripTests.FullCursor_RoundTrips_AllFields",
|
||||
"EpssCursorRoundTripTests.FromDocument_NullDocument_ReturnsEmpty",
|
||||
"EpssCursorRoundTripTests.WithPendingDocuments_DeduplicatesIds",
|
||||
"EpssCursorRoundTripTests.WithPendingMappings_DeduplicatesIds",
|
||||
"EpssCursorRoundTripTests.WithSnapshotMetadata_WhitespaceStrings_NormalizedToNull",
|
||||
"EpssCursorRoundTripTests.ToDocumentObject_SortsPendingCollections_ForDeterminism"
|
||||
],
|
||||
"behaviorVerified": [
|
||||
"Three-stage Fetch/Parse/Map connector pattern: FetchAsync stores raw document with PendingParse status, ParseAsync creates DTO and sets PendingMap, MapAsync sets Mapped",
|
||||
"ETag conditional request: second fetch with matching ETag returns 304 Not Modified, no new documents added to pending",
|
||||
"Priority band classification: 0.75->Critical, 0.70->Critical, 0.69999->High, 0.55->High, 0.40->High, 0.39999->Medium, 0.25->Medium, 0.10->Medium, 0.09999->Low, 0.05->Low, 0.00001->Low",
|
||||
"EPSS CSV parsing: typical CSV with model header produces expected snapshot observations (golden file comparison)",
|
||||
"Edge case parsing: extreme values handled correctly with deterministic output",
|
||||
"Deterministic parsing: 3 consecutive parses produce identical JSON output",
|
||||
"Resilience: missing model header handled gracefully",
|
||||
"Plugin discovery: EpssConnectorPlugin.Name returns 'epss', Create throws on null, IsAvailable returns false without registered connector",
|
||||
"Options validation: all boundary conditions verified (null BaseUri, negative CatchUpDays, zero HttpTimeout, negative MaxRetries, empty UserAgent, AirgapMode without BundlePath)",
|
||||
"Cursor round-trip: full cursor with all fields serializes to DocumentObject and deserializes back with fidelity",
|
||||
"Cursor determinism: pending collections are sorted for deterministic serialization, duplicates are deduplicated",
|
||||
"Air-gap mode configuration: AirgapMode=true requires BundlePath"
|
||||
],
|
||||
"assertionTypes": [
|
||||
"Assert.Equal on document status (PendingParse, PendingMap, Mapped)",
|
||||
"Assert.Equal on ETag value after 304",
|
||||
"Assert.Empty on PendingDocuments after 304",
|
||||
"Assert.Contains on PendingDocuments after successful fetch",
|
||||
"Assert.NotNull on stored DTO after parse",
|
||||
"Assert.Equal on EpssBand enum at each threshold boundary",
|
||||
"Assert.Equal on serialized JSON snapshot vs golden file",
|
||||
"Assert.Equal on cursor field round-trips (ModelVersion, LastProcessedDate, ETag, ContentHash, LastRowCount, UpdatedAt)",
|
||||
"Assert.Single on deduplicated GUID collections",
|
||||
"Assert.Null on whitespace-normalized fields",
|
||||
"Assert.Throws<InvalidOperationException> on validation failures",
|
||||
"FluentAssertions Should().Be() for band classification",
|
||||
"FluentAssertions Should().HaveCount(1) for determinism"
|
||||
],
|
||||
"newTestsWritten": [],
|
||||
"bugsFixed": [],
|
||||
"rawOutput": "Passed! - Failed: 0, Passed: 46, Skipped: 0, Total: 46, Duration: 1s 574ms - StellaOps.Concelier.Connector.Epss.Tests.dll (net10.0|x64)",
|
||||
"verdict": "pass"
|
||||
}
|
||||
Reference in New Issue
Block a user