Add deterministic analysis input identities

This commit is contained in:
2026-08-29 19:02:16 +00:00
parent 62de6abdbf
commit ab5751459a
12 changed files with 815 additions and 150 deletions

View File

@@ -5,6 +5,7 @@ import (
"sort"
"strings"
"gitea.maximumdirect.net/eric/narratio/internal/artifactmodel"
"gitea.maximumdirect.net/eric/narratio/internal/artifactpolicy"
"gitea.maximumdirect.net/eric/narratio/internal/config"
)
@@ -64,6 +65,9 @@ type CatalogEntry struct {
Path string
Provenance string
ProducerRunID string
Contract *artifactmodel.ContractMetadata
Checksum string
Size int64
}
// ArtifactCatalog tracks built-in, configured, and extraction artifact definitions and runtime state.
@@ -98,6 +102,7 @@ func (c *ArtifactCatalog) RegisterExtractionArtifacts(configured map[string]Extr
if _, exists := c.extractionIndex[trimmed]; exists {
return fmt.Errorf("duplicate extraction artifact key %q", trimmed)
}
def := configured[key]
sourceID := ExtractionArtifactSourceID(trimmed)
if err := c.addEntry(CatalogEntry{
SourceID: sourceID,
@@ -105,6 +110,10 @@ func (c *ArtifactCatalog) RegisterExtractionArtifacts(configured map[string]Extr
ProducerStage: "extract",
OutputKind: "notarius_lane",
Planned: true,
Contract: &artifactmodel.ContractMetadata{
MediaType: def.MediaType, SchemaID: def.SchemaID,
SchemaVersion: def.SchemaVersion, ModuleKey: def.ModuleKey,
},
}); err != nil {
return fmt.Errorf("register extraction artifact %q: %w", trimmed, err)
}
@@ -221,7 +230,7 @@ func (c *ArtifactCatalog) Lookup(sourceID string) (CatalogEntry, bool) {
return CatalogEntry{}, false
}
entry, ok := c.entries[strings.TrimSpace(sourceID)]
return entry, ok
return cloneCatalogEntry(entry), ok
}
// SourceIDForConfiguredKey returns canonical source ID for one configured key.
@@ -255,7 +264,7 @@ func (c *ArtifactCatalog) ListConfigured() []CatalogEntry {
out := make([]CatalogEntry, 0, len(keys))
for _, key := range keys {
sourceID := c.configuredIndex[key]
out = append(out, c.entries[sourceID])
out = append(out, cloneCatalogEntry(c.entries[sourceID]))
}
return out
}
@@ -272,7 +281,7 @@ func (c *ArtifactCatalog) ListExtraction() []CatalogEntry {
sort.Strings(keys)
out := make([]CatalogEntry, 0, len(keys))
for _, key := range keys {
out = append(out, c.entries[c.extractionIndex[key]])
out = append(out, cloneCatalogEntry(c.entries[c.extractionIndex[key]]))
}
return out
}
@@ -282,22 +291,36 @@ func (c *ArtifactCatalog) MarkAvailableGenerated(sourceID, path string) error {
return c.markAvailable(sourceID, path, ArtifactProvenanceGeneratedCurrentAnalyzeRun)
}
func (c *ArtifactCatalog) markAvailableFromExtractManifest(sourceID, path, producerRunID string) error {
func (c *ArtifactCatalog) markAvailableFromExtractManifest(
sourceID, path, producerRunID, checksum string,
size int64,
contract *artifactmodel.ContractMetadata,
) error {
if err := c.markAvailable(sourceID, path, ArtifactProvenanceCurrentExtractManifest); err != nil {
return err
}
entry := c.entries[strings.TrimSpace(sourceID)]
entry.ProducerRunID = strings.TrimSpace(producerRunID)
entry.Checksum = strings.TrimSpace(checksum)
entry.Size = size
entry.Contract = cloneArtifactContract(contract)
c.entries[entry.SourceID] = entry
return nil
}
func (c *ArtifactCatalog) markAvailableFromAnalyzeManifest(sourceID, path, producerRunID string) error {
func (c *ArtifactCatalog) markAvailableFromAnalyzeManifest(
sourceID, path, producerRunID, checksum string,
size int64,
contract *artifactmodel.ContractMetadata,
) error {
if err := c.markAvailable(sourceID, path, ArtifactProvenanceCurrentAnalyzeManifest); err != nil {
return err
}
entry := c.entries[strings.TrimSpace(sourceID)]
entry.ProducerRunID = strings.TrimSpace(producerRunID)
entry.Checksum = strings.TrimSpace(checksum)
entry.Size = size
entry.Contract = cloneArtifactContract(contract)
c.entries[entry.SourceID] = entry
return nil
}
@@ -318,10 +341,29 @@ func (c *ArtifactCatalog) markAvailable(sourceID, path, provenance string) error
entry.Available = true
entry.Path = trimmedPath
entry.Provenance = provenance
entry.ProducerRunID = ""
entry.Checksum = ""
entry.Size = 0
if provenance == ArtifactProvenanceGeneratedCurrentAnalyzeRun {
entry.Contract = nil
}
c.entries[normalizedID] = entry
return nil
}
func cloneCatalogEntry(entry CatalogEntry) CatalogEntry {
entry.Contract = cloneArtifactContract(entry.Contract)
return entry
}
func cloneArtifactContract(contract *artifactmodel.ContractMetadata) *artifactmodel.ContractMetadata {
if contract == nil {
return nil
}
clone := *contract
return &clone
}
func (c *ArtifactCatalog) addEntry(entry CatalogEntry) error {
if c == nil {
return fmt.Errorf("artifact catalog is nil")