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

@@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using StellaOps.AdvisoryAI.Guardrails;
using StellaOps.AdvisoryAI.Hosting;
using Xunit;
namespace StellaOps.AdvisoryAI.Tests;
public sealed class AdvisoryGuardrailOptionsBindingTests
{
[Fact]
public async Task AddAdvisoryAiCore_ConfiguresGuardrailOptionsFromServiceOptions()
{
var tempRoot = CreateTempDirectory();
var phrasePath = Path.Combine(tempRoot, "guardrail-phrases.json");
await File.WriteAllTextAsync(phrasePath, "{\n \"phrases\": [\"extract secrets\", \"dump cache\"]\n}");
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["AdvisoryAI:Guardrails:MaxPromptLength"] = "32000",
["AdvisoryAI:Guardrails:RequireCitations"] = "false",
["AdvisoryAI:Guardrails:BlockedPhraseFile"] = "guardrail-phrases.json",
["AdvisoryAI:Guardrails:BlockedPhrases:0"] = "custom override"
})
.Build();
var services = new ServiceCollection();
services.AddSingleton<IHostEnvironment>(new FakeHostEnvironment(tempRoot));
services.AddAdvisoryAiCore(configuration);
await using var provider = services.BuildServiceProvider();
var options = provider.GetRequiredService<IOptions<AdvisoryGuardrailOptions>>().Value;
options.MaxPromptLength.Should().Be(32000);
options.RequireCitations.Should().BeFalse();
options.BlockedPhrases.Should().Contain("custom override");
options.BlockedPhrases.Should().Contain("extract secrets");
options.BlockedPhrases.Should().Contain("dump cache");
}
[Fact]
public async Task AddAdvisoryAiCore_ThrowsWhenPhraseFileMissing()
{
var tempRoot = CreateTempDirectory();
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(new Dictionary<string, string?>
{
["AdvisoryAI:Guardrails:BlockedPhraseFile"] = "missing.json"
})
.Build();
var services = new ServiceCollection();
services.AddSingleton<IHostEnvironment>(new FakeHostEnvironment(tempRoot));
services.AddAdvisoryAiCore(configuration);
await using var provider = services.BuildServiceProvider();
var action = () => provider.GetRequiredService<IOptions<AdvisoryGuardrailOptions>>().Value;
action.Should().Throw<FileNotFoundException>();
}
private static string CreateTempDirectory()
{
var path = Path.Combine(Path.GetTempPath(), "advisoryai-guardrails", Guid.NewGuid().ToString("n"));
Directory.CreateDirectory(path);
return path;
}
private sealed class FakeHostEnvironment : IHostEnvironment
{
public FakeHostEnvironment(string contentRoot)
{
ContentRootPath = contentRoot;
}
public string EnvironmentName { get; set; } = Environments.Development;
public string ApplicationName { get; set; } = "StellaOps.AdvisoryAI.Tests";
public string ContentRootPath { get; set; }
= string.Empty;
}
}

View File

@@ -7,10 +7,12 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0-rc.2.25502.107" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0-rc.2.25502.107" />
</ItemGroup>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\StellaOps.AdvisoryAI\StellaOps.AdvisoryAI.csproj" />
<ProjectReference Include="..\..\StellaOps.AdvisoryAI.Hosting\StellaOps.AdvisoryAI.Hosting.csproj" />