Files
knowledge-governance/internal/httpapi/library_source_candidate.go
T
姚章浩 8d838d9cb4
build / build (push) Successful in 1m45s
feat(library): 整库发布身份、写集合与收尾边界
执行时真实时钟与持久授权回读(撤销/过期即停并保留预备份)、写集合写前落盘、
租约与 attempt 身份、恢复队列与原发送身份分离、成功收尾必须释放维护后再登记终态。
2026-11-01 11:35:10 +08:00

59 lines
2.0 KiB
Go

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
}