Documentation
¶
Overview ¶
Package resolvercatalog owns immutable, commit-bound resolver catalog publications. Resolver adapters and their semantic records are intentionally outside this package; T30.6f freezes only the lifecycle and generic canonical JSON-record envelope consumed by later materializers.
Index ¶
- Constants
- Variables
- func CleanupRetired(root string, current Manifest) error
- func CleanupRetiredContext(ctx context.Context, root string, current Manifest) error
- func CleanupStages(ctx context.Context, root string) (int, error)
- func ClearPublishing(root, repository string) error
- func IsPublishing(root, repository string) bool
- func IsRetentionRootArtifactName(name string) bool
- func IsRetentionStageName(name string) bool
- func Publishing(root, repository string) (bool, error)
- func RemoveRepository(ctx context.Context, root, repository string) error
- func RestoreArchive(archivePath, target string) error
- type ArchiveReport
- type DeclarationPublication
- type Identity
- type Manifest
- type MemberReceipt
- type Omission
- type Policy
- type Prepared
- type Publication
- func Open(ctx context.Context, root string, expected State) (*Publication, error)
- func OpenMarked(ctx context.Context, root, repository string, expectedPacks []ResolverPack) (*Publication, error)
- func OpenPublishing(ctx context.Context, root string, expected State) (*Publication, error)
- func OpenWithVisitor(ctx context.Context, root string, expected State, visit RecordVisitor) (*Publication, error)
- type ReconcileReport
- type ReconcileStore
- type RecordVisitor
- type ResolverPack
- type Stage
- type State
Constants ¶
const ( ManifestSchemaV1 = "phebs-resolver-catalog-manifest-v1" ManifestSchema = "phebs-resolver-catalog-manifest-v2" RecordSchema = "phebs-resolver-catalog-record-v1" StateSchemaV1 = "phebs-resolver-catalog-state-v1" StateSchema = "phebs-resolver-catalog-state-v2" SourceLanePolicy = resolvercatalogid.SourceLanePolicy CatalogPolicyNameV1 = "phebs-resolver-catalog-policy-v1" CatalogPolicyName = "phebs-resolver-catalog-policy-v2" MaxDeclarationPublications = 16 MaxResolverPacks = 16 MaxMembers = 256 MaxRecordsPerMember = 100_000 MaxRecords = 1_000_000 MaxRecordBytes = 1 << 20 MaxMetadataBytes = 64 << 10 MaxManifestBytes = 1 << 20 MaxMemberContentBytes = int64(64 << 20) MaxCatalogContentBytes = int64(512 << 20) // PublicationMemoryDesignBytes is the modeled per-publication design // budget, not a Go heap meter. The enforceable inputs beneath it retain // their individual byte/count caps. PublicationMemoryDesignBytes = int64(64 << 20) MaxDirectoryEntries = 32_768 MaxStagingDiskBytes = int64(520 << 20) // MaxPublicationDiskBytes models one clean old live catalog, one full // serialized stage, and both manifests during a replacement transition. // Prior-process stages and undeclared residue are outside this model and // are bounded/reclaimed through the directory lifecycle. MaxPublicationDiskBytes = int64(1034 << 20) // MaxOpenFiles is structural: lifecycle code opens at most an archive plus // one artifact, or one member plus no other lifecycle-owned descriptor. MaxOpenFiles = 2 )
const (
MaxOmissionDetails = 64
)
Variables ¶
var ( ErrInvalidIdentity = errors.New("invalid resolver catalog identity") ErrInvalidManifest = errors.New("invalid resolver catalog manifest") ErrPublishing = errors.New("resolver catalog publication is incomplete") // ErrCatalogIO distinguishes operational filesystem/read failures from // deterministic missing, malformed, or tampered derived catalog bytes. // Recovery must preserve existing authority when this error is present. ErrCatalogIO = errors.New("resolver catalog operational I/O failure") ErrLimit = errors.New("resolver catalog bound exceeded") )
var ErrNondeterministicPublication = errors.New(
"resolver catalog generation produced conflicting manifests",
)
ErrNondeterministicPublication means one resolver generation produced two different immutable manifests. Recovery must retain the store pointer and publication marker: clearing either would turn the rejected challenger into authority on the next attempt.
Functions ¶
func CleanupRetired ¶
CleanupRetired removes only generation-member names owned by repository and not referenced by the exact current manifest. The stable manifest and all foreign repository namespaces are untouched.
func CleanupRetiredContext ¶
CleanupRetiredContext is CleanupRetired with caller-owned cancellation. It is used by worker publication so the bounded directory inventory and retired artifact removal remain inside that worker's post-lock deadline.
func CleanupStages ¶
CleanupStages removes only package-owned prior-process stages and temporary marker files. Symlinks are unlinked, never followed.
func ClearPublishing ¶
ClearPublishing removes the marker only after the matching store pointer is durable. A missing marker is idempotent for recovery.
func IsPublishing ¶
func IsRetentionRootArtifactName ¶
IsRetentionRootArtifactName reports whether name is a stable installed resolver-catalog manifest or member. Markers and temporary controls are not retained publication identities.
func IsRetentionStageName ¶
IsRetentionStageName recognizes the private MkdirTemp namespace used by a resolver publication before installation.
func Publishing ¶
Publishing reports whether repository has a publication marker while preserving operational filesystem failures. A missing marker is ordinary state; other Lstat failures must not be collapsed into "not publishing" because recovery could then clear still-authoritative derived bytes.
func RemoveRepository ¶
RemoveRepository removes only artifacts in repository's cryptographic resolver-catalog namespace. It is the deletion counterpart to publication; foreign namespaces and unrelated files are never selected by decoded data.
func RestoreArchive ¶
RestoreArchive validates every header and publication in a private stage, then renames the complete filesystem set into an absent target.
Types ¶
type ArchiveReport ¶
type ArchiveReport struct {
Publications int `json:"publications"`
OmittedPublications int `json:"omitted_publications"`
OmittedArtifacts int `json:"omitted_artifacts"`
StaleMarkers int `json:"stale_markers"`
Details []Omission `json:"details,omitempty"`
TruncatedDetails int `json:"truncated_details"`
}
ArchiveReport is bounded even if an artifact directory is adversarially large. Counts remain exact; Details retains only the first fixed set.
func CreateArchiveWithReport ¶
func CreateArchiveWithReport(root, output string) (ArchiveReport, error)
CreateArchiveWithReport writes a deterministic archive containing every and only strictly valid, marker-free catalog publication.
func VerifyArchiveWithReport ¶
func VerifyArchiveWithReport(archivePath string) (ArchiveReport, error)
VerifyArchiveWithReport runs the exact restore validator in a disposable directory and returns the independently observed publication count.
type DeclarationPublication ¶
type DeclarationPublication struct {
Domain string `json:"domain"`
RunID string `json:"run_id"`
GenerationDigest string `json:"generation_digest"`
AuthoritySchema string `json:"authority_schema,omitempty"`
PlanDigest string `json:"plan_digest,omitempty"`
RootDigest string `json:"root_digest,omitempty"`
}
DeclarationPublication identifies one exact declaration plane consumed by every resolver pack. Entries are ordered by Domain.
type Identity ¶
type Identity struct {
Repository string `json:"repository"`
Commit string `json:"commit"`
UnitDigest string `json:"unit_digest"`
Declarations []DeclarationPublication `json:"declarations"`
DeclarationSetDigest string `json:"declaration_set_digest"`
CandidateManifestDigest string `json:"candidate_manifest_digest"`
SourceLanePolicy string `json:"source_lane_policy"`
ResolverPacks []ResolverPack `json:"resolver_packs"`
ResolverPackSetDigest string `json:"resolver_pack_set_digest"`
CatalogPolicy Policy `json:"catalog_policy"`
CatalogPolicyDigest string `json:"catalog_policy_digest"`
GenerationDigest string `json:"generation_digest"`
}
Identity binds every immutable input independently of member bytes.
func NewIdentity ¶
func NewIdentity( repository, commit, unitDigest, candidateManifestDigest string, declarations []DeclarationPublication, packs []ResolverPack, ) (Identity, error)
NewIdentity validates primitive inputs and derives every set/policy digest. Callers cannot supply a digest that disagrees with the ordered values.
type Manifest ¶
type Manifest struct {
Schema string `json:"schema"`
Identity Identity `json:"identity"`
Members []MemberReceipt `json:"members"`
AuthorityDigest string `json:"authority_digest,omitempty"`
Digest string `json:"digest"`
}
Manifest is the sole filesystem visibility authority.
type MemberReceipt ¶
type MemberReceipt struct {
Name string `json:"name"`
Metadata json.RawMessage `json:"metadata"`
RecordCount int `json:"record_count"`
ContentBytes int64 `json:"content_bytes"`
ContentDigest string `json:"content_digest"`
MetadataDigest string `json:"metadata_digest"`
}
MemberReceipt binds one canonical NDJSON member and its canonical metadata.
type Policy ¶
type Policy struct {
Name string `json:"name"`
RecordSchema string `json:"record_schema"`
RecordOrdering string `json:"record_ordering"`
MaxDeclarationPublications int `json:"max_declaration_publications"`
MaxResolverPacks int `json:"max_resolver_packs"`
MaxMembers int `json:"max_members"`
MaxRecordsPerMember int `json:"max_records_per_member"`
MaxRecords int `json:"max_records"`
MaxRecordBytes int `json:"max_record_bytes"`
MaxMetadataBytes int `json:"max_metadata_bytes"`
MaxManifestBytes int `json:"max_manifest_bytes"`
MaxMemberContentBytes int64 `json:"max_member_content_bytes"`
MaxCatalogContentBytes int64 `json:"max_catalog_content_bytes"`
PublicationMemoryDesignBytes int64 `json:"max_memory_bytes"`
MaxDirectoryEntries int `json:"max_directory_entries"`
MaxStagingDiskBytes int64 `json:"max_staging_disk_bytes"`
MaxPublicationDiskBytes int64 `json:"max_publication_disk_bytes"`
MaxOpenFiles int `json:"max_open_files"`
}
Policy freezes lifecycle resource bounds as digest-bearing behavior.
func FrozenPolicy ¶
func FrozenPolicy() Policy
type Prepared ¶
type Prepared struct {
// contains filtered or unexported fields
}
func (*Prepared) Discard ¶
Discard removes only this Prepared publication's package-created, flat stage before Install begins. It is idempotent on the same Prepared and deliberately refuses after an install attempt: at that point the marker and any already-renamed live artifacts belong to marked-publication recovery.
func (*Prepared) Install ¶
Install makes all members durable, then atomically renames the stable manifest last while the publication marker remains present. The caller must commit State to the store before calling ClearPublishing.
func (*Prepared) Publish ¶
func (prepared *Prepared) Publish( ctx context.Context, commit func(context.Context, State) error, ) (State, error)
Publish is the ordinary lifecycle entrypoint. A failed store commit leaves the canonical marker installed for Reconcile; the marker is removed only after commit returns nil.
type Publication ¶
type Publication struct {
// contains filtered or unexported fields
}
Publication retains descriptor identities from one cold validation. Current is therefore a metadata-only warm no-op check: it never opens or hashes member content.
func Open ¶
Open performs descriptor-stable cold validation of the exact store state. The manifest is the sole visibility authority: same-namespace residue is not admitted and is swept by CleanupRetired only after this declared set is valid, preserving the store-commit-before-cleanup crash boundary.
func OpenMarked ¶
func OpenMarked( ctx context.Context, root, repository string, expectedPacks []ResolverPack, ) (*Publication, error)
OpenMarked validates one repository's exact marked publication without mutating the catalog root. It is the runtime recovery seam for a caller that already holds that repository's repowork lock: it performs no stage cleanup, directory inventory, marker removal, store write, or foreign-repository access. The caller may commit the returned Publication.State, or use an error as the signal to deliberately clear only the named repository before staging a replacement.
The expected pack set is copied and must already be in strict name order. Pack mismatch is established from the bounded manifest before any member is opened. OpenPublishing rechecks the existing marker before and after member validation, so this function never replaces or weakens another publisher's marker fence.
func OpenPublishing ¶
OpenPublishing is restricted to recovery of a manifest made durable before its store commit; it requires and rechecks the canonical marker.
func OpenWithVisitor ¶
func OpenWithVisitor( ctx context.Context, root string, expected State, visit RecordVisitor, ) (*Publication, error)
OpenWithVisitor performs the same descriptor-stable cold validation as Open and visits each canonical record during that one content pass. It is the bounded projection hook for typed resolver consumers: member content is never reopened merely to decode already-validated records.
func (*Publication) Current ¶
func (publication *Publication) Current() bool
Current performs only lstat/control identity checks over the paths captured by Open. It does not open or hash any member.
func (*Publication) Manifest ¶
func (publication *Publication) Manifest() Manifest
func (*Publication) State ¶
func (publication *Publication) State() State
type ReconcileReport ¶
type ReconcileReport struct {
StagesRemoved int
MarkersRecovered int
PublicationsCurrent int
ReplacementsQueued int
PointersCleared int
OrphansObserved int
}
func Reconcile ¶
func Reconcile( ctx context.Context, root string, st ReconcileStore, expectedPacks []ResolverPack, ) (ReconcileReport, error)
Reconcile repairs every publication crash boundary. Queue-before-clear is deliberate: a process death can leave a redundant forced successor, but never a cleared pointer with no durable replacement request.
type ReconcileStore ¶
type ReconcileStore interface {
ListResolverCatalogPublications(context.Context) ([]store.ResolverCatalogPublication, error)
GetResolverCatalogPublication(context.Context, string) (*store.ResolverCatalogPublication, error)
ResolverCatalogPublicationCurrent(context.Context, store.ResolverCatalogPublication) (bool, error)
PublishResolverCatalog(context.Context, store.ResolverCatalogPublication) error
ClearResolverCatalogPublication(context.Context, string) error
EnqueuePending(context.Context, store.JobKind, string, bool) (*store.Job, error)
}
type RecordVisitor ¶
type RecordVisitor func( member MemberReceipt, recordIndex int, record json.RawMessage, ) error
RecordVisitor observes one canonical record while OpenWithVisitor performs the descriptor-stable cold validation pass. The raw record is valid only for the duration of the call; visitors that retain it must copy or decode it. A successful visit is provisional until OpenWithVisitor itself returns successfully because later receipt and path-fingerprint checks may still reject the publication.
type ResolverPack ¶
ResolverPack identifies one deterministic adapter generation. The empty set is the neutral T30.6f fixture and does not authorize any resolver semantics.
type Stage ¶
type Stage struct {
// contains filtered or unexported fields
}
func (*Stage) AddMember ¶
func (stage *Stage) AddMember( ctx context.Context, name string, metadata json.RawMessage, emit func(func(json.RawMessage) error) error, ) (resultErr error)
AddMember streams canonical JSON records to one member. emit may retain no lifecycle-owned resource after returning; at most one record plus small buffers is resident and only one member descriptor is open.
type State ¶
type State struct {
Schema string `json:"schema"`
Repository string `json:"repository"`
Commit string `json:"commit"`
UnitDigest string `json:"unit_digest"`
Declarations []DeclarationPublication `json:"declarations"`
DeclarationSetDigest string `json:"declaration_set_digest"`
CandidateManifestDigest string `json:"candidate_manifest_digest"`
SourceLanePolicy string `json:"source_lane_policy"`
ResolverPacks []ResolverPack `json:"resolver_packs"`
ResolverPackSetDigest string `json:"resolver_pack_set_digest"`
CatalogPolicyDigest string `json:"catalog_policy_digest"`
GenerationDigest string `json:"generation_digest"`
ManifestDigest string `json:"manifest_digest"`
AuthorityDigest string `json:"authority_digest,omitempty"`
Manifest string `json:"manifest"`
}
State is the primitive database publication pointer.