# Concelier · AGENTS Charter (Sprint 0112–0114) ## Module Scope & Working Directory - Working directory: `src/Concelier/**` (WebService, __Libraries, Storage.Postgres, analyzers, tests, seed-data). Do not edit other modules unless explicitly referenced by this sprint. - Mission: Link-Not-Merge (LNM) ingestion of advisory observations, correlation into linksets, evidence/export APIs, and deterministic telemetry. ## Roles - **Backend engineer (ASP.NET Core / PostgreSQL):** connectors, ingestion guards, linkset builder, WebService APIs, storage migrations. - **Observability/Platform engineer:** OTEL metrics/logs, health/readiness, distributed locks, scheduler safety. - **QA automation:** Testcontainers + WebApplicationFactory tests for handlers/jobs; determinism and guardrail regression harnesses. - **Docs/Schema steward:** keep LNM schemas, API references, and inline provenance docs aligned with behavior. ## Required Reading (must be treated as read before setting DOING) - `docs/README.md` - `docs/07_HIGH_LEVEL_ARCHITECTURE.md` - `docs/modules/platform/architecture-overview.md` - `docs/modules/concelier/architecture.md` - `docs/modules/concelier/link-not-merge-schema.md` - `docs/modules/provenance/guides/inline-dsse.md` (for provenance anchors/DSSE notes) - `docs/modules/concelier/prep/2025-11-22-oas-obs-prep.md` (OAS + observability prep) - `docs/modules/concelier/prep/2025-11-20-orchestrator-registry-prep.md` (orchestrator registry/control contracts) - `docs/modules/policy/cvss-v4.md` (CVSS receipts model & hashing) - `docs/product-advisories/25-Nov-2025 - Add CVSS v4.0 Score Receipts for Transparency.md` (vector provenance, DSSE expectations) - Any sprint-specific ADRs/notes linked from `docs/implplan/SPRINT_0112_0001_0001_concelier_i.md`, `SPRINT_0113_0001_0002_concelier_ii.md`, or `SPRINT_0114_0001_0003_concelier_iii.md`. ## Working Agreements - **Aggregation-Only Contract (AOC):** no derived semantics in ingestion; enforce via `AOCWriteGuard` and analyzers. Raw observations are append-only; linksets carry correlations/conflicts only. - **Determinism:** use canonical JSON writer; sort collections (fieldType, observationPath, sourceId) for cache keys; UTC ISO-8601 timestamps; stable ordering in exports/events. - **Offline-first:** avoid new external calls outside allowlisted connectors; feature flags must default safe for air-gapped deployments (`concelier:features:*`). - **Tenant safety:** every API/job must enforce tenant headers/guards; no cross-tenant leaks. - **Schema gates:** LNM schema changes require docs + tests; update `link-not-merge-schema.md` and samples together. - **Cross-module edits:** none without sprint note; if needed, log in sprint Execution Log and Decisions & Risks. - **CVSS v4.0 ingest:** when vendor advisories ship CVSS v4.0 vectors, parse without mutation, store provenance (source id + observation path), and emit vectors unchanged to Policy receipts. Do not derive fields; attach DSSE/observation refs for Policy reuse. ## Distro Backport Version Handling > **Reference:** `docs/product-advisories/archived/22-Dec-2025 - Getting Distro Backport Logic Right.md` When working with OS package advisories, follow these rules: ### Version Comparators - **RPM (RHEL/CentOS/Fedora/openSUSE):** Use `NevraComparer` in `StellaOps.Concelier.Merge.Comparers`. Compares EVR (`epoch:version-release`) using `rpmvercmp` semantics. Tilde `~` sorts before anything. - **Debian/Ubuntu:** Use `DebianEvrComparer`. Compares `epoch:upstream_version-debian_revision` using dpkg rules. Tilde `~` sorts lower than empty. - **Alpine (APK):** Use `ApkVersionComparer` (via SPRINT_2000_0003_0001). Handles `-r` and suffix ordering (`_alpha` < `_beta` < `_pre` < `_rc` < none < `_p`). ### Key Rules 1. **Never convert distro versions to SemVer.** Preserve native EVR/NEVRA/APK strings in `AffectedVersionRange`. 2. **Use `RangeKind` correctly:** `nevra` for RPM, `evr` for Debian/Ubuntu, `apk` for Alpine. 3. **Preserve release qualifiers:** `.el8_5`, `+deb12u2`, `-r0` encode backport information. 4. **Distro advisories take precedence:** When upstream says "fixed in 1.4.4" but distro claims "fixed in 1.4.3-5~deb12u2", prefer distro channel if source is trusted. 5. **Record evidence:** Store source (DSA/RHSA/USN), comparator used, installed version, fixed threshold, and result. ### Edge Cases to Handle - Epoch jumps: `1:1.2-1` > `0:9.9-9` - Tilde pre-releases: `2.0~rc1` < `2.0` - Release qualifiers: `1.2-3.el9_2` < `1.2-3.el9_3` - Rebuilds/backports: `1.2-3ubuntu0.1` vs `1.2-3` ### Test Corpus Version comparators must be tested with 50+ cases per distro. See: - `src/Concelier/__Tests/StellaOps.Concelier.Merge.Tests/Comparers/` - SPRINT_2000_0003_0002 for comprehensive test requirements ## Coding & Observability Standards - Target **.NET 10**; prefer latest C# preview features already enabled in repo. - Npgsql driver for PostgreSQL; canonical JSON mapping in Storage.Postgres. - Metrics: use `Meter` names under `StellaOps.Concelier.*`; tag `tenant`, `source`, `result` as applicable. Counters/histograms must be documented. - Logging: structured, no PII; include `tenant`, `source`, `job`, `correlationId` when available. - Scheduler/locks: one lock per connector/export job; no duplicate runs; honor `CancellationToken`. ## Testing Rules - Write/maintain tests alongside code: - Web/API: `StellaOps.Concelier.WebService.Tests` with WebApplicationFactory + Testcontainers fixtures. - Core/Linkset/Guards: `StellaOps.Concelier.Core.Tests`. - Storage: `StellaOps.Concelier.Storage.Postgres.Tests` (use in-memory or Testcontainers; determinism on ordering/hashes). - Observability/analyzers: tests in `__Analyzers` or respective test projects. - Tests must assert determinism (stable ordering/hashes), tenant guards, AOC invariants, and no derived fields in ingestion. - Prefer seeded fixtures under `src/__Tests/__Datasets/seed-data/` for repeatability; avoid network in tests. ## Delivery Discipline - Update sprint tracker status (`TODO → DOING → DONE/BLOCKED`) when you start/finish/block work; mirror decisions in Execution Log and Decisions & Risks. - If a design decision is needed, mark the task `BLOCKED` in the sprint doc and record the decision ask—do not pause the codebase. - When changing contracts (APIs, schemas, telemetry, exports), update corresponding docs and link them from the sprint Decisions & Risks section.