Advisory Observations & Linksets

Imposed rule: Work of this type or tasks of this type on this component must also be applied everywhere else it should be applied.

Audience: Concelier engineers, Policy Engine and Vuln Explorer integrators, and reviewers of Link-Not-Merge changes. Scope: The observation and linkset model, conflict handling, AOC alignment, downstream consumption, and the validation/review checklists for the Link-Not-Merge (LNM) pipeline.

The Link-Not-Merge (LNM) initiative replaces the legacy “merge” pipeline with immutable observations and correlation linksets. This guide explains how Concelier ingests advisory statements, preserves upstream truth, and produces linksets that downstream services (Policy Engine, Vuln Explorer, Console) can use without collapsing sources together.

For the governing rule set that these observations and linksets must satisfy, see the Aggregation-Only Contract Reference.


1. Model overview

1.1 Observation lifecycle

  1. Ingest – Connectors fetch upstream payloads (CSAF, OSV, vendor feeds), validate signatures, and drop any derived fields prohibited by the Aggregation-Only Contract (AOC).
  2. Persist – Concelier writes immutable advisory_observations scoped by tenant, (source.vendor, upstreamId), and contentHash. Supersedes chains capture revisions without mutating history.
  3. Expose – WebService surfaces paged/read APIs; Offline Kit snapshots include the same documents for air-gapped installs.

Observation schema highlights:

observationId = {tenant}:{source.vendor}:{upstreamId}:{revision}
tenant, source{vendor, stream, api, collectorVersion}
upstream{upstreamId, documentVersion, fetchedAt, receivedAt,
         contentHash, signature{present, format, keyId, signature}}
content{format, specVersion, raw}
identifiers{cve?, ghsa?, aliases[], osvIds[]}
linkset{purls[], cpes[], aliases[], references[], conflicts[]?}
createdAt, attributes{batchId?, replayCursor?}

1.2 Linkset lifecycle

Linksets correlate observations that describe the same vulnerable product while keeping each source intact.

  1. Seed – Observations emit normalized identifiers (purl, cpe, alias) during ingestion.
  2. Correlate – Linkset builder groups observations by tenant, product coordinates, and equivalence signals (PURL alias graph, CVE overlap, CVSS vector equality, fuzzy titles).
  3. Annotate – Detected conflicts (severity disagreements, affected-range mismatch, incompatible references) are recorded with structured payloads and preserved for UI/API export.
  4. Persist – Results land in advisory_linksets with deterministic IDs (linksetId = {tenant}:{hash(aliases+purls+seedIds)}) and append-only history for reproducibility.

Linksets never suppress or prefer one source; they provide aligned evidence so other services can apply policy.


2. Observation vs. linkset

2.1 Example sequence

  1. Red Hat PSIRT publishes RHSA-2025:1234 for OpenSSL; Concelier inserts an observation for vendor redhat with pkg:rpm/redhat/openssl@1.1.1w-12.
  2. NVD issues CVE-2025-0001; a second observation is inserted for vendor nvd.
  3. Linkset builder runs, groups the two observations, records alias and PURL overlap, and flags a CVSS disagreement (7.5 vs 7.2).
  4. Policy Engine reads the linkset, recognises the severity variance, and relies on configured rules to decide the effective output.

3. Conflict handling

Conflicts record disagreements without altering source payloads. The builder emits structured entries:

{
  "type": "severity-mismatch",
  "field": "cvss.baseScore",
  "observations": [
    {
      "source": "redhat",
      "value": "7.5",
      "vector": "AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N"
    },
    {
      "source": "nvd",
      "value": "7.2",
      "vector": "AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N"
    }
  ],
  "confidence": "medium",
  "detectedAt": "2025-10-27T14:00:00Z"
}

Supported conflict classes:

Conflict surfaces:


4. AOC alignment

Observations and linksets must satisfy Aggregation-Only Contract invariants:

Violations trigger guard errors (ERR_AOC_00x), emit aoc_violation_total metrics, and block persistence until corrected.


5. Downstream consumption

When adding new consumers, ensure they honour append-only semantics and do not mutate observation or linkset collections.


6. Validation & testing

Add fixtures whenever a new conflict type or correlation signal is introduced. Ensure canonical JSON serialization remains stable across .NET runtime updates.


7. Reviewer checklist

Confirmed against Concelier Link-Not-Merge tasks: CONCELIER-LNM-21-001..005, CONCELIER-LNM-21-101..103, CONCELIER-LNM-21-201..203.