inputs

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 18, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package inputs assembles one Wavefront evaluation from live cluster state: discovery, selector-overlap detection, source resolution, graph derivation and the engine evaluation over them (DESIGN §3, §4).

It is read-only and side-effect free — no writes, no events, no metrics, no poller — so the reconciler and the CLI derive the *same* picture from the same reads: the reconciler adds execution, status and telemetry on top, while the CLI renders the Result directly. Every pass is a full recalculation from live inputs (DESIGN D9); nothing here reads back previously published status.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Capped

func Capped[T any](list []T) []T

Capped bounds an exceptional-state list; the counts stay authoritative (DESIGN §4.1).

func HeldSources

func HeldSources(res *Result) []wavefrontv1alpha1.HeldNode

HeldSources builds the capped, source-sorted hold ledger (decision D-C). It is the ONE list: consumers write exactly this to status.held and edge-trigger against exactly this, so the ledger written and the ledger diffed are byte-identical. A source beyond StatusListCap is counted in status.Nodes.Held but neither listed nor announced until a freed slot promotes it into the cap.

Types

type GraphVerdict

type GraphVerdict struct {
	Valid   bool
	Reason  string
	Message string
}

GraphVerdict is the structural verdict on one pass: the GraphValid condition in all but name.

type Hold

type Hold struct {
	Manager string
	Kind    HoldKind
}

Hold is one source's entry in the unified hold ledger (decision D-B): Manager is "" for a Suspend hold, which names no owning actor.

type HoldKind

type HoldKind string

HoldKind distinguishes how a source is held (DESIGN §3.5.3, §10): a foreign field manager owning spec.ref.commit, or spec.suspend. Both are reported identically by the engine (NodeResult.Held, engine.go SelfHeld/AncestorHeld) and must be reported identically by consumers.

type Params

type Params struct {
	Wavefront *wavefrontv1alpha1.Wavefront
	Adapter   adapter.Adapter
	Strategy  selection.Strategy
	// Observations is the caller's own coherent snapshot of the poller; nil
	// (or a missing entry) means unobserved. Strict ordering for co-arriving
	// changes (DESIGN §3.3) is only structural if every node is evaluated
	// against the same sweep, so the snapshot is taken by the caller — once,
	// before anything reconfigures the poller — never re-read per source here.
	Observations map[types.NamespacedName]gitpoll.Observation
}

Params is everything Build needs beyond the cluster reader.

type Result

type Result struct {
	// discovery
	Nodes    map[adapter.NodeRef]adapter.Node // selected set plus dependsOn closure
	Selected map[adapter.NodeRef]bool
	Missing  map[adapter.NodeRef]bool // dependsOn targets that do not exist

	// source resolution
	Inputs map[adapter.NodeRef]engine.NodeInput
	Repos  map[types.NamespacedName]*sourcev1.GitRepository
	// NodeBySource lists every selected, pinned node referencing a source,
	// each slice in compareRefs order (decision D-D): a shared source's
	// events and status attribution need every referencing node, not just
	// whichever last overwrote a single value.
	NodeBySource map[types.NamespacedName][]adapter.NodeRef
	// Holds is the unified hold ledger (decision D-B): every source the
	// engine reports Held for, whether a hand-pin (a foreign field manager
	// owns spec.ref.commit) or a suspend (spec.suspend). It feeds
	// counts.Held, status.held[], the HoldDetected/HoldReleased edge-trigger
	// and the admission gate alike. A caller that discovers a further hold
	// while executing (an SSA conflict, pin.ErrHeld) may add to it after
	// Build returns.
	Holds   map[types.NamespacedName]Hold
	Targets []gitpoll.Target
	// UnsupportedSources lists managed sources whose ref style v1 cannot
	// sequence (DESIGN D10), demoted to gates. Recorded once per source and
	// sorted, so a caller can announce each exactly once.
	UnsupportedSources []types.NamespacedName

	// fleet
	Wavefronts *wavefrontv1alpha1.WavefrontList
	Overlap    string // name of the Wavefront whose selector overlaps this one

	// graph and evaluation
	Graph  *graph.Graph
	Cycles [][]adapter.NodeRef
	Eval   engine.Evaluation

	// Resolved and GraphChecked record how far the pass got: an aborted pass
	// has proven nothing about the fleet (Resolved false) and, before
	// derivation, nothing about the graph either (GraphChecked false).
	Resolved     bool
	GraphChecked bool
}

Result is one pass's complete read-only derivation.

It is returned non-nil even when Build fails, so a caller can still report whatever the pass managed to prove: Resolved and GraphChecked record how far it got, and every consumer must respect them rather than mistake a partial Result for a proven-empty fleet.

func Build

func Build(ctx context.Context, r client.Reader, p Params) (*Result, error)

Build performs one full read-only pass: discovery, overlap detection, source resolution, graph derivation and evaluation.

The Result is always non-nil, populated as far as the pass got, even when an error is returned.

func (*Result) GraphVerdict

func (res *Result) GraphVerdict() GraphVerdict

GraphVerdict renders the structural verdict. A selector overlap outranks a cycle: overlap suppresses admissions fleet-wide and is the more urgent configuration error to report (DESIGN §4.1).

func (*Result) SkipAdmissions

func (res *Result) SkipAdmissions() bool

SkipAdmissions reports whether every write must be suppressed for the pass, without suppressing status: selector overlap is a configuration error, not a reason to go blind (DESIGN §4.1).

type Summary

type Summary struct {
	Counts wavefrontv1alpha1.NodeCounts
	Phase  wavefrontv1alpha1.Phase
	// Blocked and Held are the capped status lists; Held is exactly
	// HeldSources(res), the ledger a caller both writes and edge-triggers
	// against (decision D-C).
	Blocked []wavefrontv1alpha1.BlockedNode
	Held    []wavefrontv1alpha1.HeldNode
	// Members is every evaluated node's derived state, sorted by
	// kind/namespace/name and capped at MembersCap; MembersOmitted counts the
	// remainder. Write-only output: nothing here or in the reconciler ever
	// reads it back (DESIGN D9).
	Members        []wavefrontv1alpha1.Member
	MembersOmitted int
	// BlockedByReason is uncapped, unlike Blocked: a gauge must count every
	// blocked node, not just the ones that fit the status list.
	BlockedByReason map[engine.BlockedReason]int
	FetchFailures   int
}

Summary is the whole publishable picture of one resolved pass: everything status carries, plus the uncapped by-reason tallies a caller may want for gauges. Deriving it here rather than in the reconciler is what lets the CLI re-derive byte-identical numbers from the same Result (DESIGN D9).

func Summarise

func Summarise(res *Result, now time.Time) Summary

Summarise derives the fleet counts, exceptional-state lists, members and phase from a completed evaluation. now supplies the fallback timestamp for a blocked node with no observation of its own; it is never used to make a decision, so a caller's clock choice cannot change what is reported.

Callers must only call this for a resolved Result: an aborted pass has derived nothing, and its zero values would claim a settled, empty fleet.

Jump to

Keyboard shortcuts

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