Implement Advisory Canonicalization and Backfill Migration
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Added AdvisoryCanonicalizer for canonicalizing advisory identifiers.
- Created EnsureAdvisoryCanonicalKeyBackfillMigration to populate advisory_key and links in advisory_raw documents.
- Introduced FileSurfaceManifestStore for managing surface manifests with file system backing.
- Developed ISurfaceManifestReader and ISurfaceManifestWriter interfaces for reading and writing manifests.
- Implemented SurfaceManifestPathBuilder for constructing paths and URIs for surface manifests.
- Added tests for FileSurfaceManifestStore to ensure correct functionality and deterministic behavior.
- Updated documentation for new features and migration steps.
This commit is contained in:
master
2025-11-07 19:54:02 +02:00
parent a1ce3f74fa
commit 515975edc5
42 changed files with 1893 additions and 336 deletions

View File

@@ -0,0 +1,45 @@
using System;
using System.IO;
namespace StellaOps.Scanner.Surface.FS;
/// <summary>
/// Configuration settings for the manifest store.
/// </summary>
public sealed class SurfaceManifestStoreOptions
{
/// <summary>
/// Gets or sets the root directory used to persist manifest payloads. When <c>null</c>,
/// the value falls back to the surface cache root.
/// </summary>
public string? RootDirectory { get; set; }
/// <summary>
/// Gets or sets the URI scheme emitted for manifest pointers.
/// </summary>
public string Scheme { get; set; } = "cas";
/// <summary>
/// Gets or sets the bucket name portion of manifest URIs.
/// </summary>
public string Bucket { get; set; } = "surface-cache";
/// <summary>
/// Gets or sets the prefix used before tenant segments within manifest URIs.
/// </summary>
public string Prefix { get; set; } = "manifests";
internal string ResolveRoot(SurfaceCacheOptions cacheOptions)
{
var root = RootDirectory;
if (string.IsNullOrWhiteSpace(root))
{
root = Path.Combine(cacheOptions.ResolveRoot(), "manifests");
}
return root!;
}
internal string ToUri(string tenantSegment, string digestHex)
=> $"{Scheme}://{Bucket}/{Prefix}/{tenantSegment}/{digestHex[..2]}/{digestHex[2..4]}/{digestHex}.json";
}