package httpapi import ( "context" "errors" "knowledge-governance/internal/governance" "knowledge-governance/internal/librarysnapshot" ) type librarySourceCandidateStore interface { LibrarySourceCandidate(context.Context, string, string) (governance.LibraryVersion, bool, error) } func configuredLibrarySource(config Config, scope string) governance.LibrarySourceIdentity { kb := config.LibrarySourceInternalKB if scope == "external" { kb = config.LibrarySourceExternalKB } return governance.LibrarySourceIdentity{Project: config.LibrarySourceProject, App: config.LibrarySourceApp, Scope: scope, TenantID: config.LibrarySourceTenantID, KnowledgeBaseID: kb} } func currentSourceCandidate(ctx context.Context, config Config, scope string) (*librarySnapshotView, error) { source := configuredLibrarySource(config, scope) id, err := source.ID() if err != nil { return nil, err } store, ok := config.Store.(librarySourceCandidateStore) if !ok { return nil, errors.New("source candidate exact query unavailable") } candidate, found, err := store.LibrarySourceCandidate(ctx, scope, id) if err != nil { return nil, err } if !found { return nil, errors.New("当前来源没有已绑定封存;旧快照须以原捕获证据核验关联,不能继承其他来源") } if candidate.Kind != governance.LibraryVersionTestSealed || candidate.Scope != scope || candidate.Evidence["source_id"] != id { return nil, errors.New("candidate source binding mismatch") } archive, err := librarysnapshot.Open(config.LibraryArchiveRoot, 256*1024*1024) if err != nil { return nil, err } defer archive.Close() manifest, err := archive.Load(candidate.SnapshotID) if err != nil { return nil, err } if manifest.Scope != scope || manifest.TenantID != source.TenantID || manifest.KnowledgeBaseID != source.KnowledgeBaseID { return nil, errors.New("candidate manifest differs from configured source") } view := librarySnapshotViewOfNoUsage(candidate.SnapshotID, manifest) view.SourceID = id view.SourceIdentity = &source return &view, nil }