Files
git.stella-ops.org/CLAUDE.md
StellaOps Bot 3f197814c5 save progress
2026-01-02 21:06:27 +02:00

27 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

StellaOps is a self-hostable, sovereign container-security platform released under AGPL-3.0-or-later. It provides reproducible vulnerability scanning with VEX-first decisioning, SBOM generation (SPDX 3.0.1 and CycloneDX 1.6), in-toto/DSSE attestations, and optional Sigstore Rekor transparency. The platform is designed for offline/air-gapped operation with regional crypto support (eIDAS/FIPS/GOST/SM).

Build Commands

# Build the entire solution
dotnet build src/StellaOps.sln

# Build a specific module (example: Concelier web service)
dotnet build src/Concelier/StellaOps.Concelier.WebService/StellaOps.Concelier.WebService.csproj

# Run the Concelier web service
dotnet run --project src/Concelier/StellaOps.Concelier.WebService

# Build CLI for current platform
dotnet publish src/Cli/StellaOps.Cli/StellaOps.Cli.csproj --configuration Release

# Build CLI for specific runtime (linux-x64, linux-arm64, osx-x64, osx-arm64, win-x64)
dotnet publish src/Cli/StellaOps.Cli/StellaOps.Cli.csproj --configuration Release --runtime linux-x64

Test Commands

# Run all tests
dotnet test src/StellaOps.sln

# Run tests for a specific project
dotnet test src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj

# Run a single test by filter
dotnet test --filter "FullyQualifiedName~TestMethodName"

# Run tests with verbosity
dotnet test src/StellaOps.sln --verbosity normal

Note: Integration tests use Testcontainers for PostgreSQL. Ensure Docker is running before executing tests.

Linting and Validation

# Lint OpenAPI specs
npm run api:lint

# Validate attestation schemas
npm run docs:attestor:validate

# Validate Helm chart
helm lint devops/helm/stellaops

# Validate Docker Compose profiles
./devops/scripts/validate-compose.sh

# Run local CI tests
./devops/scripts/test-local.sh

Architecture

Technology Stack

  • Runtime: .NET 10 (net10.0) with latest C# preview features
  • Frontend: Angular v17 (in src/Web/StellaOps.Web)
  • Database: PostgreSQL (≥16) with per-module schema isolation; see docs/db/ for specification
  • Testing: xUnit with Testcontainers (PostgreSQL), Moq, Microsoft.AspNetCore.Mvc.Testing
  • Observability: Structured logging, OpenTelemetry traces
  • NuGet: Uses standard NuGet feeds configured in nuget.config (dotnet-public, nuget-mirror, nuget.org)

Module Structure

The codebase follows a monorepo pattern with modules under src/:

Module Path Purpose
Core Platform
Authority src/Authority/ Authentication, authorization, OAuth/OIDC, DPoP
Gateway src/Gateway/ API gateway with routing and transport abstraction
Router src/Router/ Transport-agnostic messaging (TCP/TLS/UDP/RabbitMQ/Valkey)
Data Ingestion
Concelier src/Concelier/ Vulnerability advisory ingestion and merge engine
Excititor src/Excititor/ VEX document ingestion and export
VexLens src/VexLens/ VEX consensus computation across issuers
VexHub src/VexHub/ VEX distribution and exchange hub
IssuerDirectory src/IssuerDirectory/ Issuer trust registry (CSAF publishers)
Feedser src/Feedser/ Evidence collection library for backport detection
Mirror src/Mirror/ Vulnerability feed mirror and distribution
Scanning & Analysis
Scanner src/Scanner/ Container scanning with SBOM generation (11 language analyzers)
BinaryIndex src/BinaryIndex/ Binary identity extraction and fingerprinting
AdvisoryAI src/AdvisoryAI/ AI-assisted advisory analysis
ReachGraph src/ReachGraph/ Reachability graph service
Symbols src/Symbols/ Symbol resolution and debug information
Artifacts & Evidence
Attestor src/Attestor/ in-toto/DSSE attestation generation
Signer src/Signer/ Cryptographic signing operations
SbomService src/SbomService/ SBOM storage, versioning, and lineage ledger
EvidenceLocker src/EvidenceLocker/ Sealed evidence storage and export
ExportCenter src/ExportCenter/ Batch export and report generation
Provenance src/Provenance/ SLSA/DSSE attestation tooling
Policy & Risk
Policy src/Policy/ Policy engine with K4 lattice logic
RiskEngine src/RiskEngine/ Risk scoring runtime with pluggable providers
VulnExplorer src/VulnExplorer/ Vulnerability exploration and triage UI backend
Unknowns src/Unknowns/ Unknown component and symbol tracking
Operations
Scheduler src/Scheduler/ Job scheduling and queue management
Orchestrator src/Orchestrator/ Workflow orchestration and task coordination
TaskRunner src/TaskRunner/ Task pack execution engine
Notify src/Notify/ Notification toolkit (Email, Slack, Teams, Webhooks)
Notifier src/Notifier/ Notifications Studio host
PacksRegistry src/PacksRegistry/ Task packs registry and distribution
TimelineIndexer src/TimelineIndexer/ Timeline event indexing
Replay src/Replay/ Deterministic replay engine
Integration
CLI src/Cli/ Command-line interface (Native AOT)
Zastava src/Zastava/ Container registry webhook observer
Web src/Web/ Angular 17 frontend SPA
API src/Api/ OpenAPI contracts and governance
Infrastructure
Cryptography src/Cryptography/ Crypto plugins (FIPS, eIDAS, GOST, SM, PQ)
Telemetry src/Telemetry/ OpenTelemetry traces, metrics, logging
Graph src/Graph/ Call graph and reachability data structures
Signals src/Signals/ Runtime signal collection and correlation
AirGap src/AirGap/ Air-gapped deployment support
AOC src/Aoc/ Append-Only Contract enforcement (Roslyn analyzers)

Note: See docs/modules/<module>/architecture.md for detailed module dossiers.

Code Organization Patterns

  • Libraries: src/<Module>/__Libraries/StellaOps.<Module>.*
  • Tests: src/<Module>/__Tests/StellaOps.<Module>.*.Tests/
  • Plugins: Follow naming StellaOps.<Module>.Connector.* or StellaOps.<Module>.Plugin.*
  • Shared test infrastructure: StellaOps.Concelier.Testing and StellaOps.Infrastructure.Postgres.Testing provide PostgreSQL fixtures

Naming Conventions

  • All modules are .NET 10 projects, except the UI (Angular)
  • Module projects: StellaOps.<ModuleName>
  • Libraries/plugins common to multiple modules: StellaOps.<LibraryOrPlugin>
  • Each project lives in its own folder

Key Glossary

  • OVAL — Vendor/distro security definition format; authoritative for OS packages
  • NEVRA / EVR — RPM and Debian version semantics for OS packages
  • PURL / SemVer — Coordinates and version semantics for OSS ecosystems
  • KEV — Known Exploited Vulnerabilities (flag only)

Coding Rules

Core Principles

  1. Determinism: Outputs must be reproducible - stable ordering, UTC ISO-8601 timestamps, immutable NDJSON where applicable
  2. Offline-first: Remote host allowlist, strict schema validation, avoid hard-coded external dependencies unless explicitly allowed
  3. Plugin architecture: Concelier connectors, Authority plugins, Scanner analyzers are all plugin-based
  4. VEX-first decisioning: Exploitability modeled in OpenVEX with lattice logic for stable outcomes

Implementation Guidelines

  • Follow .NET 10 and Angular v17 best practices
  • Apply SOLID principles (SRP, OCP, LSP, ISP, DIP) when designing services, libraries, and tests
  • Keep in mind the nuget versions are controlled centrally by src/Directory* files, not via csproj
  • Maximise reuse and composability
  • Never regress determinism, ordering, or precedence
  • Every change must be accompanied by or covered by tests
  • Gated LLM usage (only where explicitly configured)

Test Layout

  • Module tests: src/<Module>/__Tests/StellaOps.<Module>.<Component>.Tests/
  • Global tests: src/__Tests/{Category}/ (Integration, Acceptance, Load, Security, Chaos, E2E, etc.)
  • Shared testing libraries: src/__Tests/__Libraries/StellaOps.*.Testing/
  • Benchmarks & golden corpus: src/__Tests/__Benchmarks/
  • Ground truth datasets: src/__Tests/__Datasets/
  • Tests use xUnit, Testcontainers for PostgreSQL integration tests
  • See src/__Tests/AGENTS.md for detailed test infrastructure guidance

Code Quality & Determinism Rules

These rules were distilled from a comprehensive audit of 324+ projects. They address the most common recurring issues and must be followed by all implementers.

8.1) Compiler & Warning Discipline

Rule Guidance
Enable TreatWarningsAsErrors All projects must set <TreatWarningsAsErrors>true</TreatWarningsAsErrors> in the .csproj or via Directory.Build.props. Relaxed warnings mask regressions and code quality drift.
<!-- In .csproj or Directory.Build.props -->
<PropertyGroup>
  <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>

8.2) Deterministic Time & ID Generation

Rule Guidance
Inject TimeProvider / ID generators Never use DateTime.UtcNow, DateTimeOffset.UtcNow, Guid.NewGuid(), or Random.Shared directly in production code. Inject TimeProvider (or ITimeProvider) and IGuidGenerator abstractions.
// BAD - nondeterministic, hard to test
public class BadService
{
    public Record CreateRecord() => new Record
    {
        Id = Guid.NewGuid(),
        CreatedAt = DateTimeOffset.UtcNow
    };
}

// GOOD - injectable, testable, deterministic
public class GoodService(TimeProvider timeProvider, IGuidGenerator guidGenerator)
{
    public Record CreateRecord() => new Record
    {
        Id = guidGenerator.NewGuid(),
        CreatedAt = timeProvider.GetUtcNow()
    };
}

8.3) ASCII-Only Output

Rule Guidance
No mojibake or non-ASCII glyphs Use ASCII-only characters in comments, output strings, and log messages. No ƒ?, , , , , or box-drawing characters. When Unicode is truly required, use explicit escapes (\uXXXX) and document the rationale.
// BAD - non-ASCII glyphs
Console.WriteLine("✓ Success → proceeding");
// or mojibake comments like: // ƒ+ validation passed

// GOOD - ASCII only
Console.WriteLine("[OK] Success - proceeding");
// Comment: validation passed

8.4) Test Project Requirements

Rule Guidance
Every library needs tests All production libraries/services must have a corresponding *.Tests project covering: (a) happy paths, (b) error/edge cases, (c) determinism, and (d) serialization round-trips.
src/
  Scanner/
    __Libraries/
      StellaOps.Scanner.Core/
    __Tests/
      StellaOps.Scanner.Core.Tests/   <-- Required

8.5) Culture-Invariant Parsing

Rule Guidance
Use InvariantCulture Always use CultureInfo.InvariantCulture for parsing and formatting dates, numbers, percentages, and any string that will be persisted, hashed, or compared. Current culture causes locale-dependent, nondeterministic behavior.
// BAD - culture-sensitive
var value = double.Parse(input);
var formatted = percentage.ToString("P2");

// GOOD - invariant culture
var value = double.Parse(input, CultureInfo.InvariantCulture);
var formatted = percentage.ToString("P2", CultureInfo.InvariantCulture);

8.6) DSSE PAE Consistency

Rule Guidance
Single DSSE PAE implementation Use one spec-compliant DSSE PAE helper (StellaOps.Attestation.DsseHelper or equivalent) across the codebase. DSSE v1 requires ASCII decimal lengths and space separators. Never reimplement PAE encoding.
// BAD - custom PAE implementation
var pae = $"DSSEv1 {payloadType.Length} {payloadType} {payload.Length} ";

// GOOD - use shared helper
var pae = DsseHelper.ComputePreAuthenticationEncoding(payloadType, payload);

8.7) RFC 8785 JSON Canonicalization

Rule Guidance
Use shared RFC 8785 canonicalizer For digest/signature inputs, use a shared RFC 8785-compliant JSON canonicalizer with: sorted keys, minimal escaping per spec, no exponent notation for numbers, no trailing/leading zeros. Do not use UnsafeRelaxedJsonEscaping or CamelCase naming for canonical outputs.
// BAD - non-canonical JSON
var json = JsonSerializer.Serialize(obj, new JsonSerializerOptions
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});

// GOOD - use shared canonicalizer
var canonicalJson = CanonicalJsonSerializer.Serialize(obj);
var digest = ComputeDigest(canonicalJson);

8.8) CancellationToken Propagation

Rule Guidance
Propagate CancellationToken Always propagate CancellationToken through async call chains. Never use CancellationToken.None in production code except at entry points where no token is available.
// BAD - ignores cancellation
public async Task ProcessAsync(CancellationToken ct)
{
    await _repository.SaveAsync(data, CancellationToken.None);  // Wrong!
    await Task.Delay(1000);  // Missing ct
}

// GOOD - propagates cancellation
public async Task ProcessAsync(CancellationToken ct)
{
    await _repository.SaveAsync(data, ct);
    await Task.Delay(1000, ct);
}

8.9) HttpClient via Factory

Rule Guidance
Use IHttpClientFactory Never new HttpClient() directly. Use IHttpClientFactory with configured timeouts and retry policies via Polly or Microsoft.Extensions.Http.Resilience. Direct HttpClient creation risks socket exhaustion.
// BAD - direct instantiation
public class BadService
{
    public async Task FetchAsync()
    {
        using var client = new HttpClient();  // Socket exhaustion risk
        await client.GetAsync(url);
    }
}

// GOOD - factory with resilience
public class GoodService(IHttpClientFactory httpClientFactory)
{
    public async Task FetchAsync()
    {
        var client = httpClientFactory.CreateClient("MyApi");
        await client.GetAsync(url);
    }
}

// Registration with timeout/retry
services.AddHttpClient("MyApi")
    .ConfigureHttpClient(c => c.Timeout = TimeSpan.FromSeconds(30))
    .AddStandardResilienceHandler();

8.10) Path/Root Resolution

Rule Guidance
Explicit CLI options for paths Do not derive repository root from AppContext.BaseDirectory with parent directory walks. Use explicit CLI options (--repo-root) or environment variables. Provide sensible defaults with clear error messages.
// BAD - fragile parent walks
var repoRoot = Path.GetFullPath(Path.Combine(
    AppContext.BaseDirectory, "..", "..", "..", ".."));

// GOOD - explicit option with fallback
[Option("--repo-root", Description = "Repository root path")]
public string? RepoRoot { get; set; }

public string GetRepoRoot() =>
    RepoRoot ?? Environment.GetEnvironmentVariable("STELLAOPS_REPO_ROOT")
    ?? throw new InvalidOperationException("Repository root not specified. Use --repo-root or set STELLAOPS_REPO_ROOT.");

8.11) Test Categorization

Rule Guidance
Correct test categories Tag tests correctly: [Trait("Category", "Unit")] for pure unit tests, [Trait("Category", "Integration")] for tests requiring databases, containers, or network. Don't mix DB/network tests into unit suites.
// BAD - integration test marked as unit
public class UserRepositoryTests  // Uses Testcontainers/Postgres
{
    [Fact]  // Missing category, runs with unit tests
    public async Task Save_PersistsUser() { ... }
}

// GOOD - correctly categorized
[Trait("Category", "Integration")]
public class UserRepositoryTests
{
    [Fact]
    public async Task Save_PersistsUser() { ... }
}

[Trait("Category", "Unit")]
public class UserValidatorTests
{
    [Fact]
    public void Validate_EmptyEmail_ReturnsFalse() { ... }
}

8.12) No Silent Stubs

Rule Guidance
Unimplemented code must throw Placeholder code must throw NotImplementedException or return an explicit error/unsupported status. Never return success (null, empty results, or success codes) from unimplemented paths.
// BAD - silent stub masks missing implementation
public async Task<Result> ProcessAsync()
{
    // TODO: implement later
    return Result.Success();  // Ships broken feature!
}

// GOOD - explicit failure
public async Task<Result> ProcessAsync()
{
    throw new NotImplementedException("ProcessAsync not yet implemented. See SPRINT_XYZ.");
}

8.13) Immutable Collection Returns

Rule Guidance
Return immutable collections Public APIs must return IReadOnlyList<T>, ImmutableArray<T>, or defensive copies. Never expose mutable backing stores that callers can mutate.
// BAD - exposes mutable backing store
public class BadRegistry
{
    private readonly List<string> _scopes = new();
    public List<string> Scopes => _scopes;  // Callers can mutate!
}

// GOOD - immutable return
public class GoodRegistry
{
    private readonly List<string> _scopes = new();
    public IReadOnlyList<string> Scopes => _scopes.AsReadOnly();
    // or: public ImmutableArray<string> Scopes => _scopes.ToImmutableArray();
}

8.14) Options Validation at Startup

Rule Guidance
ValidateOnStart for options Use ValidateDataAnnotations() and ValidateOnStart() for options. Implement IValidateOptions<T> for complex validation. All required config must be validated at startup, not at first use.
// BAD - no validation until runtime failure
services.Configure<MyOptions>(config.GetSection("My"));

// GOOD - validated at startup
services.AddOptions<MyOptions>()
    .Bind(config.GetSection("My"))
    .ValidateDataAnnotations()
    .ValidateOnStart();

// With complex validation
public class MyOptionsValidator : IValidateOptions<MyOptions>
{
    public ValidateOptionsResult Validate(string? name, MyOptions options)
    {
        if (options.Timeout <= TimeSpan.Zero)
            return ValidateOptionsResult.Fail("Timeout must be positive");
        return ValidateOptionsResult.Success;
    }
}

8.15) No Backup Files in Source

Rule Guidance
Exclude backup/temp artifacts Add backup patterns (*.Backup.tmp, *.bak, *.orig) to .gitignore. Regularly audit for and remove stray artifacts. Consolidate duplicate tools/harnesses.
# .gitignore additions
*.Backup.tmp
*.bak
*.orig
*~

8.16) Test Production Code, Not Reimplementations

Rule Guidance
Helpers call production code Test helpers must call production code, not reimplement algorithms (Merkle trees, DSSE PAE, parsers, canonicalizers). Only mock I/O and network boundaries. Reimplementations cause test/production drift.
// BAD - test reimplements production logic
[Fact]
public void Merkle_ComputesCorrectRoot()
{
    // Custom Merkle implementation in test
    var root = TestMerkleHelper.ComputeRoot(leaves);  // Drift risk!
    Assert.Equal(expected, root);
}

// GOOD - test exercises production code
[Fact]
public void Merkle_ComputesCorrectRoot()
{
    // Uses production MerkleTreeBuilder
    var root = MerkleTreeBuilder.ComputeRoot(leaves);
    Assert.Equal(expected, root);
}

8.17) Bounded Caches with Eviction

Rule Guidance
No unbounded Dictionary caches Do not use ConcurrentDictionary or Dictionary for caching without eviction policies. Use bounded caches with TTL/LRU eviction (MemoryCache with size limits, or external cache like Valkey). Document expected cardinality and eviction behavior.
// BAD - unbounded growth
private readonly ConcurrentDictionary<string, CacheEntry> _cache = new();

public void Add(string key, CacheEntry entry)
{
    _cache[key] = entry;  // Never evicts, memory grows forever
}

// GOOD - bounded with eviction
private readonly MemoryCache _cache = new(new MemoryCacheOptions
{
    SizeLimit = 10_000
});

public void Add(string key, CacheEntry entry)
{
    _cache.Set(key, entry, new MemoryCacheEntryOptions
    {
        Size = 1,
        SlidingExpiration = TimeSpan.FromMinutes(30)
    });
}

8.18) DateTimeOffset for PostgreSQL timestamptz

Rule Guidance
Use GetFieldValue<DateTimeOffset> PostgreSQL timestamptz columns must be read via reader.GetFieldValue<DateTimeOffset>(), not reader.GetDateTime(). GetDateTime() loses offset information and causes UTC/local confusion. Store and retrieve all timestamps as UTC DateTimeOffset.
// BAD - loses offset information
var createdAt = reader.GetDateTime(reader.GetOrdinal("created_at"));

// GOOD - preserves offset
var createdAt = reader.GetFieldValue<DateTimeOffset>(reader.GetOrdinal("created_at"));

Documentation Updates

When scope, contracts, or workflows change, update the relevant docs under:

  • docs/modules/** - Module architecture dossiers
  • docs/api/ - API documentation
  • docs/risk/ - Risk documentation
  • docs/airgap/ - Air-gap operation docs

Role-Based Behavior

When working in this repository, behavior changes based on the role specified:

As Implementer (Default for coding tasks)

  • Work only inside the module's directory defined by the sprint's "Working directory"
  • Cross-module edits require explicit notes in commit/PR descriptions
  • Do not ask clarification questions - if ambiguity exists:
    • Mark the task as BLOCKED in the sprint Delivery Tracker
    • Add a note in Decisions & Risks describing the issue
    • Skip to the next unblocked task
  • Maintain status tracking: TODO → DOING → DONE/BLOCKED in sprint files
  • Read the module's AGENTS.md before coding in that module

As Project Manager

Create implementation sprint files under docs/implplan/ using the mandatory sprint filename format:

SPRINT_<IMPLID>_<BATCHID>_<MODULEID>_<topic_in_few_words>.md

  • <IMPLID>: implementation epoch (e.g., 20251219). Determine by scanning existing docs/implplan/SPRINT_*.md and using the highest epoch; if none exist, use today's epoch.
  • <BATCHID>: 001, 002, etc. — grouping when more than one sprint is needed for a feature.
  • <MODULEID>: FE (Frontend), BE (Backend), AG (Agent), LB (library), BE (Backend), AG (Agent), LB (library), 'SCANNER' (scanner), 'AUTH' (Authority), 'CONCEL' (Concelier), 'CONCEL-ASTRA' - (Concelier Astra source connecto) and etc.
  • <topic_in_few_words>: short topic description.
  • If any existing sprint file name or internal format deviates from the standard, rename/normalize it and record the change in its Execution Log.
  • Normalize sprint files to standard template while preserving content
  • Ensure module AGENTS.md files exist and are up to date

As Product Manager

  • Review advisories in docs/product-advisories/
  • Check for overlaps with docs/product-advisories/archived/
  • Validate against module docs and existing implementations
  • Hand over to project manager role for sprint/task definition

Task Workflow

Status Discipline

Always update task status in docs/implplan/SPRINT_*.md:

  • TODO - Not started
  • DOING - In progress
  • DONE - Completed
  • BLOCKED - Waiting on decision/clarification

Prerequisites

Before coding, confirm required docs are read:

  • docs/README.md
  • docs/07_HIGH_LEVEL_ARCHITECTURE.md
  • docs/modules/platform/architecture-overview.md
  • Relevant module dossier (e.g., docs/modules/<module>/architecture.md)
  • Module-specific AGENTS.md file

Git Rules

  • Never use git reset unless explicitly told to do so
  • Never skip hooks (--no-verify, --no-gpg-sign) unless explicitly requested

Configuration

  • Sample configs: etc/concelier.yaml.sample, etc/authority.yaml.sample
  • Plugin manifests: etc/authority.plugins/*.yaml
  • NuGet sources: Package cache in .nuget/packages/, public sources configured in nuget.config

Documentation

  • Architecture overview: docs/07_HIGH_LEVEL_ARCHITECTURE.md
  • Module dossiers: docs/modules/<module>/architecture.md
  • Database specification: docs/db/SPECIFICATION.md
  • PostgreSQL operations: docs/operations/postgresql-guide.md
  • API/CLI reference: docs/09_API_CLI_REFERENCE.md
  • Offline operation: docs/24_OFFLINE_KIT.md
  • Quickstart: docs/10_CONCELIER_CLI_QUICKSTART.md
  • Sprint planning: docs/implplan/SPRINT_*.md

CI/CD

Folder Structure

The CI/CD infrastructure uses a two-tier organization:

Folder Purpose
.gitea/workflows/ Gitea Actions workflow YAML files (87+)
.gitea/scripts/ CI/CD scripts called by workflows
devops/ Deployment, tooling, and operational configs

CI/CD Scripts (.gitea/scripts/)

.gitea/scripts/
├── build/      # Build orchestration (build-cli.sh, build-multiarch.sh)
├── test/       # Test execution (test-lane.sh, determinism-run.sh)
├── validate/   # Validation (validate-sbom.sh, validate-helm.sh)
├── sign/       # Signing (sign-signals.sh, publish-attestation.sh)
├── release/    # Release automation (build_release.py, verify_release.py)
├── metrics/    # Performance metrics (compute-reachability-metrics.sh)
├── evidence/   # Evidence bundles (upload-all-evidence.sh)
└── util/       # Utilities (cleanup-runner-space.sh)

DevOps Folder (devops/)

devops/
├── compose/        # Docker Compose profiles (dev, stage, prod, airgap)
├── helm/           # Helm charts (stellaops)
├── docker/         # Dockerfiles (platform, crypto-profile, ci)
├── telemetry/      # OpenTelemetry, Prometheus, Grafana configs
├── services/       # Service-specific configs (authority, crypto, signals)
├── offline/        # Air-gap and offline deployment
├── observability/  # Alerts, SLOs, incident management
├── database/       # PostgreSQL and MongoDB configs
├── ansible/        # Ansible playbooks
├── gitlab/         # GitLab CI templates
├── releases/       # Release manifests
├── tools/          # Development tools (callgraph, corpus, feeds)
└── scripts/        # DevOps scripts (test-local.sh, validate-compose.sh)

Key Workflows

Workflow Purpose
build-test-deploy.yml Main build, test, and deployment pipeline
test-matrix.yml Unified test execution with TRX reporting
module-publish.yml Per-module NuGet and container publishing
release-suite.yml Full suite release (Ubuntu-style versioning)
cli-build.yml CLI multi-platform builds
scanner-determinism.yml Scanner output reproducibility tests
policy-lint.yml Policy validation

Versioning

  • Suite releases: Ubuntu-style YYYY.MM with codenames (e.g., "2026.04 Nova")
  • Module releases: Semantic versioning MAJOR.MINOR.PATCH
  • See docs/releases/VERSIONING.md for full documentation

Environment Variables

  • STELLAOPS_BACKEND_URL - Backend API URL for CLI
  • STELLAOPS_TEST_POSTGRES_CONNECTION - PostgreSQL connection string for integration tests
  • StellaOpsEnableCryptoPro - Enable GOST crypto support (set to true in build)