References¶
Every library, framework, API, and tool this repo actually depends on, plus
"learn more" reading on the architectural patterns in play. Kept in sync
with ../plain/learn-more.md (same list, softer
explanations, no code).
Backend (.NET)¶
| Library / API | Version in this repo | GitHub | Official docs |
|---|---|---|---|
| .NET / ASP.NET Core | net10.0 (FleetMissionControl.Api.csproj) |
dotnet/aspnetcore | learn.microsoft.com/aspnet/core |
| ASP.NET Core Minimal APIs | built into net10.0 | dotnet/aspnetcore | Minimal APIs overview |
| ASP.NET Core SignalR | built into net10.0 (Microsoft.AspNetCore.SignalR) |
dotnet/aspnetcore | SignalR overview |
| Microsoft.AspNetCore.OpenApi | built into net10.0 (AddOpenApi()/MapOpenApi()) |
dotnet/aspnetcore | OpenAPI in ASP.NET Core |
| System.Text.Json | BCL | dotnet/runtime | System.Text.Json overview |
| System.Security.Cryptography (HMACSHA256, SHA256) | BCL | dotnet/runtime | Cryptography model |
| xUnit.net | test project | xunit/xunit | xunit.net docs |
| Stryker.NET (dotnet-stryker) | dotnet tool (.config/dotnet-tools.json) |
stryker-mutator/stryker-net | stryker-mutator.io/docs |
| JetBrains InspectCode (ReSharper CLT) | dotnet tool, CI inspectcode job |
JetBrains/resharper-unity (closed-source CLI, distributed via NuGet) | InspectCode command-line tool |
Frontend (Angular)¶
| Library / API | Version in this repo | GitHub | Official docs |
|---|---|---|---|
| Angular | 22.0.6 (frontend/package.json) |
angular/angular | angular.dev |
| Angular signals | part of @angular/core 22 |
angular/angular | Signals guide |
| Angular standalone components | part of @angular/core 22 |
angular/angular | Standalone components guide |
| Angular service worker (PWA) | @angular/service-worker |
angular/angular | Angular service worker intro |
| @microsoft/signalr (JS client) | 10.0.0 | dotnet/aspnetcore | JavaScript SignalR client |
| NSwag | dev dependency, drives nswag.json |
RicoSuter/NSwag | NSwag docs |
| TypeScript | 6.0.3 | microsoft/TypeScript | typescriptlang.org/docs |
| Vitest | frontend test runner (vitest.config.ts, stryker.config.json) |
vitest-dev/vitest | vitest.dev |
| ESLint (Angular config) | eslint.config.js, ng lint |
eslint/eslint | eslint.org/docs |
| Stryker (JS/TS mutation testing) | npm run test:mutation |
stryker-mutator/stryker-js | stryker-mutator.io/docs |
IDE hosts¶
| Platform / API | GitHub | Official docs |
|---|---|---|
| VS Code Extension API + Webview API | microsoft/vscode | Webview API guide |
| Visual Studio SDK (VSIX / VSCT) | microsoft/VSSDK-Extensibility-Samples | Visual Studio extensibility docs |
| Microsoft Edge WebView2 | MicrosoftEdge/WebView2Samples | WebView2 docs |
External services this API talks to¶
| Service | Used for | Docs |
|---|---|---|
| Jira Cloud REST API v3 | JiraBoardService — read-only FLT board fetch |
Jira Cloud platform REST API |
| Tailscale | the tailnet perimeter this API binds to and trusts as the read boundary | tailscale.com/kb |
CI / tooling¶
| Tool | Used for | GitHub | Docs |
|---|---|---|---|
| GitHub Actions | CI orchestration (.github/workflows/ci.yml) |
actions/runner | docs.github.com/actions |
| actionlint | lints the workflow file itself (.github/actionlint.yaml) |
rhysd/actionlint | actionlint README |
| Semgrep | SAST, CI security job (via the semgrep/semgrep Docker image) |
semgrep/semgrep | semgrep.dev/docs |
| Mermaid | diagrams embedded directly in this markdown | mermaid-js/mermaid | mermaid.js.org |
| D2 | C4 context/container diagrams, rendered to committed SVG | terrastruct/d2 | d2lang.com |
| C4 model | the notation the D2 diagrams follow (Context/Container levels) | — | c4model.com |
Learn more: the patterns in play¶
Minimal APIs. Program.cs registers every route as a lambda against a
RouteGroupBuilder, with .RequireFleetAuth() as a composable
IEndpointFilter rather than a controller attribute. This repo leans on
route groups (app.MapGroup("/api")) specifically so the write-vs-read auth
posture is visible at the call site of every route, not buried in a
controller base class. Read: Route groups in Minimal APIs.
HMAC job signing. AgentRunDispatcher.Sign/RepoRegistryReader.Sign
both build a canonical |-joined string over a fixed, order-significant
field list and HMAC-SHA256 it with a shared secret — the same shape as AWS
SigV4 or a webhook signature, scaled down to a single shared key because
every party (this API, every fleet listener) already holds it out-of-band.
Read: HMAC — Wikipedia, OWASP message
integrity cheat
sheet.
File-queue dispatch. Jobs are files, not HTTP calls: AgentRunDispatcher
writes a signed JSON file into a shared directory
({DispatchRoot}/{pc}/inbox/{jobId}.json) that a separate listener process
polls and drains. This trades instant delivery for a much smaller attack
surface (no host:port to resolve or SSRF through) and durability (a job
survives a dead listener; it just waits). Read: File-based queueing / the
"maildir" pattern — the same
write-temp-then-atomic-rename idea this repo's WriteJsonAtomic helpers use.
SignalR hubs. FleetHub : Hub<IFleetClient> is a strongly-typed hub with
zero client→server methods — a push-only broadcast channel, not RPC. Read:
Strongly typed hubs.
Capability routing. CapabilityRouter.Plan is a pure function from
(request, quota snapshot, recent runs) to a RoutingDecision — a
precedence chain (hard constraint → explicit override → auto) that is fully
unit-testable because nothing in it does I/O. This is the same shape as a
feature-flag/policy evaluator: inputs in, a decision object out, the caller
owns every side effect. Read: Strategy pattern
(the shape CapabilityRouter/TierLadder/AvailabilityGate all share).
Container queries. The responsive layout in status-wall.component.ts
sizes off .cockpit-container's own inline-size, not the viewport — so an
embedded IDE panel narrower than the browser window still gets the right
layout. Read: CSS container queries — MDN.
Angular Signals. FleetStore holds every piece of live state as a
signal(), with computed() derivations (workers, gateRuns) instead of
RxJS pipes for anything that doesn't need async composition. Read:
Angular Signals guide.
OpenAPI-driven client generation. The backend is the source of truth;
the frontend never hand-writes a DTO. dotnet build emits
openapi/FleetMissionControl.Api.json, NSwag turns it into
fleet-api.generated.ts, and CI fails if either artifact is stale relative
to its source. Read: NSwag: OpenAPI/Swagger client generation.
The C4 model. docs/diagrams/c4-context.d2 and c4-container.d2 follow
the C4 model's first two levels (System Context, Containers) — a fixed
vocabulary (Person / Software System / Container / Component) chosen
specifically so the diagram means the same thing to anyone who already knows
the notation. Read: c4model.com.