A .NET 10 backend that turns an incident signal into a reviewable, evidence-backed triage report.
IncidentCompass explores a narrow question: can an LLM choose useful investigation steps without receiving authority over credentials, persistence or external side effects? The model may delegate work and propose tool calls. The backend owns tool grants, budgets, evidence checks, the audit ledger and the final report commit.
Version v0.2.0 adds governed OTLP intake, memory synchronization, immutable report history,
server-owned incident tenancy and operational hardening.
- The API accepts native OTLP trace/log protobuf exports or an OTel-shaped, user or tester signal, redacts sensitive fields, groups it into a fault and creates a durable triage job.
- The Worker claims the job and reloads the exact versioned configuration captured at intake.
- The orchestrator may delegate to analysis and memory workers. Each role receives only its configured tools, and every proposed call passes deterministic backend policy.
publish_reportsucceeds only when cited evidence resolves to allowed artifacts from the same job and, for attempt-scoped artifacts, the current attempt. Policy decisions, model calls, tool activity and publication are recorded in the ledger.
The screenshot is from the deterministic v0.1.1 demo: a KnownIncident report with one cited
runbook and 22 ledger events. It demonstrates the backend path and review surface, not classification
accuracy for arbitrary models or incidents.
The normal local path uses OpenAI-compatible chat and embedding endpoints. On Windows and macOS,
Docker Compose points to host.docker.internal:1234 by default.
Copy-Item .env.example .env
# Set exact model ids in .env when your provider requires them.
dotnet run --project src/IncidentCompass.Api -- config validate
powershell -ExecutionPolicy Bypass -File scripts/demo.ps1The script builds PostgreSQL, API, Worker and Tester containers, runs the local scenarios and prints
URLs for the fault ledger and triage report. Use scripts/demo.ps1 -Mock only when you need the
fully deterministic mock path. The configurable ingestion payload limit must be between 1 KiB and 1 MiB. The upper bound caps per-request buffering; the 1 KiB lower bound prevents a misconfiguration that rejects ordinary small OTLP exports. MaxAttributesBytes must be positive and no greater than MaxPayloadBytes. The default limits are 64 KiB and 16 KiB. See Quickstart and
Local demo walkthrough for provider settings, port overrides and manual steps.
- The orchestration loop is bounded by backend-owned worker, token, wall-clock and reprompt budgets.
- Worker tools are role-scoped and fail closed when they are unknown, ungranted or denied by policy.
- Report evidence is resolved against stored artifacts instead of trusting model-authored citations.
- The investigation can be reconstructed from durable ledger and configuration snapshot records.
- Automated tests remain deterministic and do not call real providers by default.
Model quality is separate from these guarantees. A weak or incompatible model may still fail to complete the multi-turn trajectory or reach a correct conclusion.
- Layered-monolith .NET 10 application with Clean Architecture boundaries and a lightweight internal dispatcher/pipeline.
- Signal intake with source normalization, configurable redaction, fingerprinting, grouping, triage job creation and grounded intake artifacts.
- OpenAI-compatible model and embedding adapters for the normal runtime path, with explicit mock adapters for tests and deterministic checks.
- Configured orchestrator and worker roles, typed output schemas, role-scoped tools and ledger-backed policy decisions.
- PostgreSQL/pgvector incident memory with governed
memory_search, file-backed seed identity and snapshotted per-service current-release markers for documentation fit. - Backend-grounded triage reports plus fault, report and ledger read APIs.
- Docker Compose packaging with a stock OTel Collector route and an HTTP-only Tester that does not reference application assemblies.
- Server-owned incident-data tenant scope for intake and fault/report/ledger reads; demo tenant headers are never trusted.
- Signal intake handler - normalizes, redacts, groups and persists an incoming signal.
- Governed investigation processor - runs the bounded orchestrator/worker loop.
- Worker tool rule engine - applies configured grants and policy rules before tool execution.
- Report evidence grounder - resolves model-proposed references against citable artifacts from the active attempt.
Implementation and refactoring were heavily assisted by coding agents. Igor Lagutin owned the product scope, architecture, task decomposition, acceptance criteria, review decisions and release gates. Generated changes were treated as untrusted until the relevant build, tests, Docker scenarios, code-organization checks and vulnerability gate passed.
Failures and trade-offs stay visible in the repository. The recorded real-model smoke results include unsuccessful runs instead of presenting only the best outcome.
flowchart LR
Client["Client / API consumer"] --> Api["IncidentCompass.Api"]
Tester["IncidentCompass.Tester"] --> Api
Api --> App["IncidentCompass.Application"]
Worker["IncidentCompass.Worker"] --> App
App --> Domain["IncidentCompass.Domain"]
Infrastructure["IncidentCompass.Infrastructure"] --> App
Infrastructure --> Postgres["PostgreSQL + pgvector"]
Infrastructure --> Providers["OpenAI-compatible providers"]
Infrastructure --> TestProviders["Mock providers (tests only)"]
IncidentCompass.Application is organized by feature folder: Core, Governance, Intake,
Investigation and Memory. Infrastructure implements persistence, provider, configuration and
memory adapters. The API remains transport-focused. The Worker owns job claiming and governed
background processing. Tester is an external HTTP client for the local scenarios.
Start with Architecture, Security model, Observability and Trade-offs.
IncidentCompass is reference-quality software for local review, not a production incident platform. The current scope does not provide enterprise authentication, a stable extension framework, a UI, external actions, an MCP surface, a usage dashboard or a general document-ingestion system. Local credentials, demo auth and Compose defaults must be replaced before any non-local deployment.
- Quickstart
- Local demo walkthrough
- Architecture
- Security model
- Model gateway
- Observability
- Code organization
- Versioning and release flow
- Release candidate notes for v0.2.0
- Published v0.1.1 notes
IncidentCompass was bootstrapped from the dotnet-genai-starter repository's layered .NET structure and model/embedding gateway boundaries. It was then specialized into one incident-triage workflow. Chat, general RAG document ingestion, evaluations, usage dashboards and MCP product surfaces were removed because they do not belong to this project's scope.
