# 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.