# Remediation Module Architecture > **Status: Partially implemented.** Core remediation APIs exist, and marketplace source endpoints now run with persistence-backed list/get/upsert behavior. Remaining areas are still incremental (template lifecycle depth, contributor workflow hardening, and broader policy integration). ## Overview The Remediation module provides a developer-facing signed-PR remediation marketplace for the Stella Ops platform. It enables developers to discover, apply, and verify community-contributed or vendor-supplied fix templates for known vulnerabilities (CVEs). ## Key Concepts ### Fix Templates Structured remediation patches tied to specific CVE + PURL combinations. Templates include unified diff content, version range applicability, and trust scores from contributor history. ### PR Submissions Tracks the lifecycle of a remediation pull request from submission through scanning, merging, and post-merge verification. Each submission produces attestation evidence including reachability deltas and fix-chain DSSE envelopes. ### Contributors Community members or vendors who submit fix templates. Each contributor has a trust score computed from their verification history (verified fixes, rejections). ### Marketplace Sources Curated collections of fix templates from community, partner, or vendor origins. Sources are rated independently and can be enabled or disabled per tenant. ## Domain Model ```text FixTemplate (remediation.fix_templates) |- CveId (text, indexed) |- Purl (text, indexed - pkg:type/name) |- VersionRange (semver range) |- PatchContent (unified diff) |- Status (pending/verified/rejected) |- TrustScore (0.0-1.0) |- DsseDigest (nullable - signed envelope hash) `- ContributorId / SourceId (foreign keys) PrSubmission (remediation.pr_submissions) |- FixTemplateId (nullable FK) |- PrUrl, RepositoryUrl, SourceBranch, TargetBranch |- CveId (text, indexed) |- Status (opened/scanning/merged/verified/failed/inconclusive) |- PreScanDigest, PostScanDigest |- ReachabilityDeltaDigest, FixChainDsseDigest |- Verdict (fixed/partial/not_fixed/inconclusive) `- ContributorId Contributor (remediation.contributors) |- Username (unique) |- VerifiedFixes, TotalSubmissions, RejectedSubmissions `- TrustScore (computed) MarketplaceSource (remediation.marketplace_sources) |- Key (tenant-scoped unique key) |- SourceType (community/partner/vendor) |- Enabled, TrustScore `- LastSyncAt ``` ## Trust Scoring Contributor trust score formula: ```text score = clamp((verified * 1.0 - rejected * 0.5) / max(total, 1), 0, 1) ``` Trust tiers: - **trusted** (> 0.8): Verified track record - **established** (> 0.5): Growing history - **new** (> 0.2): Recently joined - **untrusted** (<= 0.2): Insufficient or negative history ## API Surface All endpoints are under `/api/v1/remediation/`. ### Templates - `GET /templates` - List fix templates (filter by CVE, PURL) - `GET /templates/{id}` - Get template detail - `POST /templates` - Create template (requires `remediation.submit`) ### Submissions - `GET /submissions` - List PR submissions - `GET /submissions/{id}` - Get submission with attestation chain - `POST /submissions` - Submit PR for verification - `GET /submissions/{id}/status` - Pipeline status ### Matching - `GET /match?cve=...&purl=...&version=...` - Find applicable fix templates ### Contributors - `GET /contributors` - List contributors - `GET /contributors/{username}` - Profile with trust score ### Sources - `GET /sources` - List marketplace sources - `GET /sources/{key}` - Source detail - `POST /sources` - Create/update source (requires `remediation.manage`) Implemented source API contract (2026-03-04): - Request model for upsert (`POST /sources`): `key`, `name`, `url`, `sourceType`, `enabled`, `trustScore`, `lastSyncAt`. - Deterministic behavior: - key normalization uses lowercase invariant - list ordering is key-based ordinal ordering - upsert is idempotent by tenant + source key - Validation: - key pattern: `^[a-z0-9][a-z0-9._-]{0,63}$` - sourceType allowed values: `community`, `partner`, `vendor` - trustScore range: `0..1` - url must be an absolute `http`/`https` URL when provided - Tenant isolation: - all source endpoints require tenant context (`RequireTenant`) - repository operations are tenant-scoped for list/get/upsert behavior ## Authorization Policies | Policy | Description | |--------|-------------| | `remediation.read` | Read templates, submissions, contributors, sources | | `remediation.submit` | Create templates and submit PRs | | `remediation.manage` | Manage marketplace sources, verify/reject templates | ## Runtime Storage Contract (2026-03-05) Remediation runtime storage is now selected through `Remediation:Storage:Driver` (or `Storage:Driver`) with explicit startup validation: - `postgres` (default): - Required settings: `ConnectionStrings:Default` or `Remediation:Storage:Postgres:ConnectionString`. - Optional schema override: `Remediation:Storage:Postgres:SchemaName` (defaults to `remediation`). - Behavior: repositories are wired with `RemediationDataSource` and Postgres-backed constructors. - Startup: fails fast when required connection configuration is missing. - `inmemory`: - Allowed only in `Test`/`Testing` environment profiles. - Intended for deterministic automated tests only. - Startup: fails fast outside test profiles. This removes implicit production-like in-memory behavior and makes storage mode explicit and auditable. Migration notes: - Legacy webservice wiring that instantiated parameterless repository constructors has been removed. - Existing deployments must provide a Postgres connection string (or explicitly run with `inmemory` in `Test`/`Testing` profiles). - Integration tests should pin `REMEDIATION__STORAGE__DRIVER=inmemory` under a testing environment profile for deterministic non-network execution. ## Service Integration Baseline (2026-03-05) - Router integration enabled (`serviceName: remediation`) with endpoint refresh on startup. - Local alias binding/logging enabled via `remediation.stella-ops.local`. - CORS and tenant middleware are part of the default request pipeline before endpoint execution. ## Verification Pipeline 1. PR submitted (status: `opened`) 2. Pre-merge scan captures baseline SBOM digest 3. PR merged (status: `merged`) 4. Post-merge scan captures updated SBOM digest 5. Reachability delta computed between pre and post digests 6. Fix-chain DSSE envelope signed 7. Verdict determined: `fixed`, `partial`, `not_fixed`, or `inconclusive` ## Webhook Integration The `RemediationPrWebhookHandler` in the Signals module detects remediation PRs by: - Title convention: `fix(CVE-XXXX-NNNNN): description` - Label: `stella-ops/remediation` ## Module Location ```text src/Remediation/ |- StellaOps.Remediation.Core/ - Domain models, interfaces, services |- StellaOps.Remediation.WebService/ - API endpoints, Program.cs |- StellaOps.Remediation.Persistence/ - SQL migrations, repositories |- __Tests/StellaOps.Remediation.Tests/ - Repository/domain unit tests `- __Tests/StellaOps.Remediation.WebService.Tests/ - Source endpoint integration tests ``` ## Related Sprints - SPRINT_20260220_010: Registry and persistence - SPRINT_20260220_011: Signals webhook handler - SPRINT_20260220_012: Verification pipeline - SPRINT_20260220_013: Matching, sources, policy - SPRINT_20260220_014: UI components - SPRINT_20260220_015: Documentation ## Related Contracts - `docs/contracts/remediation-pr-v1.md` ## Advisory Gap Status (2026-03-04 Batch) Status: - Advisory gap `REM-001` is closed for marketplace sources. Closed behaviors: - `GET /api/v1/remediation/sources` returns persisted tenant-scoped sources with deterministic ordering. - `GET /api/v1/remediation/sources/{key}` resolves persisted records (no unconditional stub `source_not_found` path). - `POST /api/v1/remediation/sources` performs validated upsert and no longer returns `501`. - Marketplace source repository abstraction and implementation are wired through DI: - `IMarketplaceSourceRepository` - `PostgresMarketplaceSourceRepository` Verification evidence: - `dotnet test src/Remediation/__Tests/StellaOps.Remediation.Tests/StellaOps.Remediation.Tests.csproj -m:1 -v minimal` - `28` passed. - `dotnet test src/Remediation/__Tests/StellaOps.Remediation.WebService.Tests/StellaOps.Remediation.WebService.Tests.csproj -m:1 -v minimal` - `4` passed. Tracking sprint: - `docs/implplan/SPRINT_20260304_308_Remediation_marketplace_sources_api_completion.md`