resolvercatalog

package
v0.0.0-...-3d6ecf2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

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

View Source
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
)
View Source
const (
	MaxOmissionDetails = 64
)

Variables

View Source
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")
)
View Source
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

func CleanupRetired(root string, current Manifest) error

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

func CleanupRetiredContext(ctx context.Context, root string, current Manifest) error

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

func CleanupStages(ctx context.Context, root string) (int, error)

CleanupStages removes only package-owned prior-process stages and temporary marker files. Symlinks are unlinked, never followed.

func ClearPublishing

func ClearPublishing(root, repository string) error

ClearPublishing removes the marker only after the matching store pointer is durable. A missing marker is idempotent for recovery.

func IsPublishing

func IsPublishing(root, repository string) bool

func IsRetentionRootArtifactName

func IsRetentionRootArtifactName(name string) bool

IsRetentionRootArtifactName reports whether name is a stable installed resolver-catalog manifest or member. Markers and temporary controls are not retained publication identities.

func IsRetentionStageName

func IsRetentionStageName(name string) bool

IsRetentionStageName recognizes the private MkdirTemp namespace used by a resolver publication before installation.

func Publishing

func Publishing(root, repository string) (bool, error)

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

func RemoveRepository(ctx context.Context, root, repository string) error

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

func RestoreArchive(archivePath, target string) error

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.

func (Manifest) State

func (manifest Manifest) State() State

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 Omission

type Omission struct {
	Name   string `json:"name"`
	Reason string `json:"reason"`
}

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

func (prepared *Prepared) Discard() error

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

func (prepared *Prepared) Install(ctx context.Context) (State, error)

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

func Open(ctx context.Context, root string, expected State) (*Publication, error)

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

func OpenPublishing(ctx context.Context, root string, expected State) (*Publication, error)

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

type ResolverPack struct {
	Name    string `json:"name"`
	Version string `json:"version"`
}

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 NewStage

func NewStage(root string, identity Identity) (*Stage, error)

NewStage creates an fsync'd, package-owned stage on the catalog filesystem.

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.

func (*Stage) Discard

func (stage *Stage) Discard() error

Discard removes only this Stage's package-created, flat unpublished directory. It is idempotent on the same Stage and never inventories or cleans the catalog root. Once Seal succeeds, the returned Prepared owns the directory and must be discarded instead.

func (*Stage) Seal

func (stage *Stage) Seal(ctx context.Context) (*Prepared, error)

Seal writes and syncs the canonical manifest in the stage. The returned Prepared value can be installed exactly once.

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.

func ParseRetentionManifest

func ParseRetentionManifest(raw []byte) (State, int64, error)

ParseRetentionManifest validates canonical manifest metadata without opening or hashing any member payload and returns its committed receipt.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL