feat(scanner): Implement Deno analyzer and associated tests
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Added Deno analyzer with comprehensive metadata and evidence structure.
- Created a detailed implementation plan for Sprint 130 focusing on Deno analyzer.
- Introduced AdvisoryAiGuardrailOptions for managing guardrail configurations.
- Developed GuardrailPhraseLoader for loading blocked phrases from JSON files.
- Implemented tests for AdvisoryGuardrailOptions binding and phrase loading.
- Enhanced telemetry for Advisory AI with metrics tracking.
- Added VexObservationProjectionService for querying VEX observations.
- Created extensive tests for VexObservationProjectionService functionality.
- Introduced Ruby language analyzer with tests for simple and complex workspaces.
- Added Ruby application fixtures for testing purposes.
This commit is contained in:
master
2025-11-12 10:01:54 +02:00
parent 0e8655cbb1
commit babb81af52
75 changed files with 3346 additions and 187 deletions

View File

@@ -902,9 +902,8 @@ var advisoryChunksEndpoint = app.MapGet("/advisories/{advisoryKey}/chunks", asyn
}
var duration = timeProvider.GetElapsedTime(requestStart);
var guardrailCounts = cacheHit
? ImmutableDictionary<AdvisoryChunkGuardrailReason, int>.Empty
: buildResult.Telemetry.GuardrailCounts;
var guardrailCounts = buildResult.Telemetry.GuardrailCounts ??
ImmutableDictionary<AdvisoryChunkGuardrailReason, int>.Empty;
telemetry.TrackChunkResult(new AdvisoryAiChunkRequestTelemetry(
tenant,

View File

@@ -51,7 +51,7 @@ internal sealed class AdvisoryAiTelemetry : IAdvisoryAiTelemetry
AdvisoryAiMetrics.BuildCacheTags(tenant, "hit"));
}
if (!telemetry.CacheHit && telemetry.GuardrailCounts.Count > 0)
if (telemetry.GuardrailCounts.Count > 0)
{
foreach (var kvp in telemetry.GuardrailCounts)
{

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.Metrics;
using FluentAssertions;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.Concelier.WebService.Services;
using StellaOps.Concelier.WebService.Diagnostics;
using Xunit;
namespace StellaOps.Concelier.WebService.Tests;
public sealed class AdvisoryAiTelemetryTests : IDisposable
{
private readonly MeterListener _listener;
private readonly List<Measurement<long>> _guardrailMeasurements = new();
public AdvisoryAiTelemetryTests()
{
_listener = new MeterListener
{
InstrumentPublished = (instrument, listener) =>
{
if (instrument.Meter.Name == AdvisoryAiMetrics.MeterName)
{
listener.EnableMeasurementEvents(instrument);
}
}
};
_listener.SetMeasurementEventCallback<long>((instrument, measurement, tags, state) =>
{
if (instrument.Meter.Name == AdvisoryAiMetrics.MeterName &&
instrument.Name == "advisory_ai_guardrail_blocks_total")
{
_guardrailMeasurements.Add(new Measurement<long>(measurement, tags, state));
}
});
_listener.Start();
}
[Fact]
public void TrackChunkResult_RecordsGuardrailCounts_ForCacheHits()
{
var telemetry = new AdvisoryAiTelemetry(NullLogger<AdvisoryAiTelemetry>.Instance);
var guardrailCounts = new Dictionary<AdvisoryChunkGuardrailReason, int>
{
{ AdvisoryChunkGuardrailReason.BelowMinimumLength, 2 }
};
telemetry.TrackChunkResult(new AdvisoryAiChunkRequestTelemetry(
Tenant: "tenant-a",
AdvisoryKey: "CVE-2099-0001",
Result: "ok",
Truncated: false,
CacheHit: true,
ObservationCount: 1,
SourceCount: 1,
ChunkCount: 1,
Duration: TimeSpan.FromMilliseconds(5),
GuardrailCounts: guardrailCounts));
_guardrailMeasurements.Should().ContainSingle();
var measurement = _guardrailMeasurements[0];
measurement.Value.Should().Be(2);
measurement.Tags.Should().Contain(tag => tag.Key == "cache" && (string?)tag.Value == "hit");
}
public void Dispose()
{
_listener.Dispose();
}
}