13 KiB
Here’s a condensed “Stella Ops Developer Guidelines” based on the official engineering docs and dev guides.
0. Where to start
- Dev docs index: The main entrypoint is
Development Guides & Tooling(docs/technical/development/README.md). It links to coding standards, test strategy, performance workbook, plug‑in SDK, examples, and more. (Gitea: Git with a cup of tea) - If a term is unfamiliar: Check the one‑page Glossary of Terms first. (Stella Ops)
- Big picture: Stella Ops is an SBOM‑first, offline‑ready container security platform; a lot of design decisions (determinism, signatures, policy DSL, SBOM delta scans) flow from that. (Stella Ops)
1. Core engineering principles
From Coding Standards & Contributor Guide: (Gitea: Git with a cup of tea)
- SOLID first – especially interface & dependency inversion.
- 100‑line file rule – if a file grows >100 physical lines, split or refactor.
- Contracts vs runtime – public DTOs and interfaces live in lightweight
*.Contractsprojects; implementations live in sibling runtime projects. - Single composition root – DI wiring happens in
StellaOps.Web/Program.csand each plug‑in’sIoCConfigurator. Nothing else creates a service provider. - No service locator – constructor injection only; no global
ServiceProvideror static service lookups. - Fail‑fast startup – validate configuration before the web host starts listening.
- Hot‑load compatibility – avoid static singletons that would survive plug‑in unload; don’t manually load assemblies outside the built‑in loader.
These all serve the product goals of deterministic, offline, explainable security decisions. (Stella Ops)
2. Repository layout & layering
From the repo layout section: (Gitea: Git with a cup of tea)
-
Top‑level structure (simplified):
src/ backend/ StellaOps.Web/ # ASP.NET host + composition root StellaOps.Common/ # logging, helpers StellaOps.Contracts/ # DTO + interface contracts … more runtime projects plugins-sdk/ # plug‑in templates & abstractions frontend/ # Angular workspace tests/ # mirrors src 1‑to‑1 -
Rules:
- No “Module” folders or nested solution hierarchies.
- Tests mirror
src/structure 1:1; no test code in production projects. - New features follow feature folder layout (e.g.,
Scan/ScanService.cs,Scan/ScanController.cs).
3. Naming, style & language usage
Key conventions: (Gitea: Git with a cup of tea)
- Namespaces: file‑scoped,
StellaOps.*. - Interfaces:
Iprefix (IScannerRunner). - Classes/records: PascalCase (
ScanRequest,TrivyRunner). - Private fields:
camelCase(no leading_). - Constants:
SCREAMING_SNAKE_CASE. - Async methods: end with
Async. - Usings: outside namespace, sorted, no wildcard imports.
- File length: keep ≤100 lines including
usingand braces (enforced by tooling).
C# feature usage: (Gitea: Git with a cup of tea)
- Nullable reference types on.
- Use
recordfor immutable DTOs. - Prefer pattern matching over long
switchcascades. Span/Memoryonly when you’ve measured that you need them.- Use
await foreachinstead of manual iterator loops.
Formatting & analysis:
dotnet formatmust be clean; StyleCop + security analyzers + CodeQL run in CI and are treated as gates. (Gitea: Git with a cup of tea)
4. Dependency injection, async & concurrency
DI policy (core + plug‑ins): (Gitea: Git with a cup of tea)
-
Exactly one composition root per process (
StellaOps.Web/Program.cs). -
Plug‑ins contribute through:
[ServiceBinding]attributes for simple bindings, or- An
IoCConfigurator : IDependencyInjectionRoutinefor advanced setups.
-
Default lifetime is scoped. Use singletons only for truly stateless, thread‑safe helpers.
-
Never use a service locator or manually build nested service providers except in tests.
Async & threading: (Gitea: Git with a cup of tea)
- All I/O is async; avoid
.Result/.Wait(). - Library code uses
ConfigureAwait(false). - Control concurrency with channels or
Parallel.ForEachAsync, not ad‑hocTask.Runloops.
5. Tests, tooling & quality gates
The Automated Test‑Suite Overview spells out all CI layers and budgets. (Gitea: Git with a cup of tea)
Test layers (high‑level):
-
Unit tests: xUnit.
-
Property‑based tests: FsCheck.
-
Integration:
- API integration with Testcontainers.
- DB/merge flows using Mongo + Redis.
-
Contracts: gRPC breakage checks with Buf.
-
Frontend:
- Unit tests with Jest.
- E2E tests with Playwright.
- Lighthouse runs for performance & accessibility.
-
Non‑functional:
- Load tests via k6.
- Chaos experiments (CPU/OOM) using Docker tooling.
- Dependency & license scanning.
- SBOM reproducibility/attestation checks.
Quality gates (examples): (Gitea: Git with a cup of tea)
- API unit test line coverage ≥ ~85%.
- API P95 latency ≤ ~120 ms in nightly runs.
- Δ‑SBOM warm scan P95 ≤ ~5 s on reference hardware.
- Lighthouse perf score ≥ ~90, a11y ≥ ~95.
Local workflows:
- Use
./scripts/dev-test.shfor “fast” local runs and--fullfor the entire stack (API, UI, Playwright, Lighthouse, etc.). Needs Docker and modern Node. (Gitea: Git with a cup of tea) - Some suites use Mongo2Go + an OpenSSL 1.1 shim; others use a helper script to spin up a local
mongodfor deeper debugging. (Gitea: Git with a cup of tea)
6. Plug‑ins & connectors
The Plug‑in SDK Guide is your bible for schedule jobs, scanner adapters, TLS providers, notification channels, etc. (Gitea: Git with a cup of tea)
Basics:
-
Use
.NETtemplates to scaffold:dotnet new stellaops-plugin-schedule -n MyPlugin.Schedule --output src -
At publish time, copy signed artefacts to:
src/backend/Stella.Ops.Plugin.Binaries/<MyPlugin>/ MyPlugin.dll MyPlugin.dll.sig -
The backend:
- Verifies the Cosign signature.
- Enforces
[StellaPluginVersion]compatibility. - Loads plug‑ins in isolated
AssemblyLoadContexts.
DI entrypoints:
- For simple cases, mark implementations with
[ServiceBinding(typeof(IMyContract), ServiceLifetime.Scoped, …)]. - For more control, implement
IoCConfigurator : IDependencyInjectionRoutineand configure services/options inRegister(...). (Gitea: Git with a cup of tea)
Examples:
- Schedule job: implement
IJob.ExecuteAsync, add[StellaPluginVersion("X.Y.Z")], register cron withservices.AddCronJob<MyJob>("0 15 * * *"). - Scanner adapter: implement
IScannerRunnerand register viaservices.AddScanner<MyAltScanner>("alt"); document Docker sidecars if needed. (Gitea: Git with a cup of tea)
Signing & deployment:
-
Publish, sign with Cosign, optionally zip:
dotnet publish -c Release -p:PublishSingleFile=true -o out cosign sign --key $COSIGN_KEY out/MyPlugin.Schedule.dll -
Copy into the backend container (e.g.,
/opt/plugins/) and restart. -
Unsigned DLLs are rejected when
StellaOps:Security:DisableUnsigned=false. (Gitea: Git with a cup of tea)
Marketplace:
- Tag releases like
plugin-vX.Y.Z, attach the signed ZIP, and submit metadata to the community plug‑in index so it shows up in the UI Marketplace. (Gitea: Git with a cup of tea)
7. Policy DSL & security decisions
For policy authors and tooling engineers, the Stella Policy DSL (stella‑dsl@1) doc is key. (Stella Ops)
Goals:
- Deterministic: same inputs → same findings on every machine.
- Declarative: no arbitrary loops, network calls, or clocks.
- Explainable: each decision carries rule, inputs, rationale.
- Offline‑friendly and reachability‑aware (SBOM + advisories + VEX + reachability). (Stella Ops)
Structure:
-
One
policyblock per.stellafile, with:metadata(description, tags).profileblocks (severity, trust, reachability adjustments).ruleblocks (when/thenlogic).- Optional
settings. (Stella Ops)
Context & built‑ins:
- Namespaces like
sbom,advisory,vex,env,telemetry,secret,profile.*, etc. (Stella Ops) - Helpers such as
normalize_cvss,risk_score,vex.any,vex.latest,sbom.any_component,exists,coalesce, and secrets‑specific helpers. (Stella Ops)
Rules of thumb:
- Always include a clear
becausewhen you changestatusorseverity. (Stella Ops) - Avoid catch‑all suppressions (
when true+status := "suppressed"); the linter will flag them. (Stella Ops) - Use
stella policy lint/compile/simulatein CI and locally; test in sealed (offline) mode to ensure no network dependencies. (Stella Ops)
8. Commits, PRs & docs
From the commit/PR checklist: (Gitea: Git with a cup of tea)
Before opening a PR:
-
Use Conventional Commit prefixes (
feat:,fix:,docs:, etc.). -
Run
dotnet formatanddotnet test; both must be green. -
Keep new/changed files within the 100‑line guideline.
-
Update XML‑doc comments for any new public API.
-
If you add/change a public contract:
- Update the relevant markdown docs.
- Update JSON schema / API descriptions as needed.
-
Ensure static analyzers and CI jobs relevant to your change are passing.
For new test layers or jobs, also update the test‑suite overview and metrics docs so the CI configuration stays discoverable. (Gitea: Git with a cup of tea)
9. Licensing & reciprocity
Stella Ops ships under AGPL‑3.0‑or‑later with a strong reciprocity clause: (Stella Ops)
- You may run, study, modify, and redistribute it, including as a hosted service.
- If you run a modified version for others over a network, you must make that exact source code available to those users.
- Official containers are signed and include SBOMs and attestations; verify them with Cosign as described on the license/security pages. (Stella Ops)
When you build extensions:
- Keep plug‑ins compatible with AGPL expectations around combined works.
- Don’t embed proprietary logic into the core without checking license implications.
10. If you just want a “first contribution” recipe
A practical path that follows the guidelines:
-
Clone the main repo; skim Coding Standards, Test Suite Overview, and the Dev Guides & Tooling index. (Gitea: Git with a cup of tea)
-
Get
dotnet, Docker, Node set up; run./scripts/dev-test.shto make sure your environment is healthy. (Gitea: Git with a cup of tea) -
Pick a small issue (docs, small refactor, or new test), make changes respecting:
- 100‑line files,
- DI patterns,
- naming & style.
-
Add/adjust tests plus any affected docs or JSON schemas.
-
Run tests + formatting locally, push, and open a PR with a conventional title and a short “how I tested this” note.
If you tell me what you’re planning to work on (plug‑in, policy pack, core feature, or UI), I can turn this into a very concrete checklist tailored to that slice of Stella Ops.