Add new features and tests for AirGap and Time modules
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Introduced `SbomService` tasks documentation.
- Updated `StellaOps.sln` to include new projects: `StellaOps.AirGap.Time` and `StellaOps.AirGap.Importer`.
- Added unit tests for `BundleImportPlanner`, `DsseVerifier`, `ImportValidator`, and other components in the `StellaOps.AirGap.Importer.Tests` namespace.
- Implemented `InMemoryBundleRepositories` for testing bundle catalog and item repositories.
- Created `MerkleRootCalculator`, `RootRotationPolicy`, and `TufMetadataValidator` tests.
- Developed `StalenessCalculator` and `TimeAnchorLoader` tests in the `StellaOps.AirGap.Time.Tests` namespace.
- Added `fetch-sbomservice-deps.sh` script for offline dependency fetching.
This commit is contained in:
master
2025-11-20 23:29:54 +02:00
parent 65b1599229
commit 79b8e53441
182 changed files with 6660 additions and 1242 deletions

View File

@@ -0,0 +1,57 @@
# Console Consumption of LNM Linksets (Sprint 110)
Goal: unblock CONCELIER-CONSOLE-23-001..003 by defining how Console reads Link-Not-Merge (LNM) data now that the schema is frozen (2025-11-17) and cache plan exists.
## Data sources
- Primary collection: `advisory_linksets` (see `docs/modules/concelier/link-not-merge-schema.md`).
- Cache: `advisory_linkset_cache` (see `docs/modules/concelier/operations/lnm-cache-plan.md`). Console should read from cache when present; fall back to live rebuild otherwise.
## API shape (WebService)
- Endpoint to expose via Console: `GET /v1/lnm/linksets/{advisoryId}`
- Query: `source` (required), `tenant`, optional `includeConflicts=true|false` (default true).
- Response JSON (deterministic key order):
```json
{
"advisoryId": "GHSA-123",
"source": "ghsa",
"observations": ["<mongoId>", "<mongoId2>"],
"normalized": {
"purls": ["pkg:npm/foo@1.0.0"],
"versions": ["1.0.0"],
"ranges": [],
"severities": [{"system":"cvssv3","score":7.5}]
},
"conflicts": [
{"field":"severities","reason":"disagreement","values":["7.5","9.8"]}
],
"provenance": {
"observationHashes": ["..."],
"toolVersion": "lnm-1.0"
},
"createdAt": "2025-11-20T00:00:00Z"
}
```
- Sorting: observations sorted by `source, advisoryId, fetchedAt` before hashing; response preserves that order.
- Caching: when cache hit, return cached document; when miss, rebuild, write cache, then return.
## Console rendering contract
- Fields to surface:
- `normalized.purls` (list) and `normalized.versions`
- `conflicts` if non-empty: show field + reason text; keep order as returned.
- `provenance.observationHashes` as “evidence anchors” (list); do not prettify.
- Tenant header required; no cross-tenant leakage. Scope `concelier:lnm.read`.
## Error handling
- 404 when linkset missing for advisory/source.
- 409 when tenant header missing/invalid.
- Deterministic error body: `{ "error": "<code>", "message": "..." }`.
## Telemetry (reuse existing meters)
- Increment `lnm.cache.hit_total` / `lnm.cache.write_total` as defined in cache plan.
- Log template on returns: `lnm_console_success tenant={Tenant} advisoryId={AdvisoryId} source={Source} cached={Cached}`.
## Owners
- Concelier Console Guild (primary)
- Concelier Core Guild (review)
This document is authoritative for CONCELIER-CONSOLE-23-001..003 in Sprint 110.

View File

@@ -0,0 +1,33 @@
# Concelier LNM Cache Plan (Sprint 110)
Purpose: finalize structured caching fields now that Link-Not-Merge (LNM) schema is frozen (2025-11-17) and Evidence Locker contract is published.
## Cache payload shape
- Source: `advisory_linksets` collection (see `docs/modules/concelier/link-not-merge-schema.md`).
- Cache entry key: `{tenant}:{advisoryId}:{source}`.
- Cached fields (deterministic order):
- `observations` (ObjectId list, already sorted by source, advisoryId, fetchedAt)
- `normalized.purls`, `normalized.versions`, `normalized.ranges`, `normalized.severities`
- `conflicts` array (field, reason, values)
- `provenance.observationHashes`
- `builtByJobId`, `createdAt`
- Exclude mutable/derived fields; cache is rebuilt on ingestion replay, not updated in place.
## Storage & eviction
- Collection: `advisory_linkset_cache` (per-tenant index `{tenantId:1, advisoryId:1, source:1}` unique).
- Eviction: TTL on `createdAt` disabled by default; cache is replaced when a newer `provenance.observationHashes` differs.
- Determinism: cache documents written via canonical JSON writer (sorted keys); timestamps UTC.
## API exposure
- WebService: surface cached linksets via existing `/v1/lnm/linksets/{advisoryId}?source=...` (read-through); if cache miss, rebuild synchronously and store.
- Console: may rely on this cache for Advisory AI surfaces; no new payload fields required.
## Telemetry
- Meter `StellaOps.Concelier.Linksets` (existing) to add counters: `lnm.cache.write_total{result}`, `lnm.cache.hit_total{source}`; histogram `lnm.cache.rebuild_ms` for synchronous rebuilds. (To be wired in subsequent sprint.)
## Alignment
- Schema source of truth: `docs/modules/concelier/link-not-merge-schema.md` (frozen v1).
- Evidence Locker contract: `docs/modules/evidence-locker/attestation-contract.md` informs provenance fields; no shape changes required.
## Ownership
- Concelier Core + WebService guilds.