Documentation
¶
Overview ¶
Package fingerprint extracts a structured cluster identity from a snapshot's collector measurements and compares it against a recipe's criteria.
A Fingerprint records the cluster-identity dimensions used to bind a snapshot to a recipe — service (eks/gke/aks/oke/kind/lke), accelerator (h100/gb200/b200/a100/l40/rtx-pro-6000), OS (ubuntu/rhel/cos/amazonlinux/talos plus raw VERSION_ID), Kubernetes server version, region, total node count, and GPU node count. Each dimension records the resolved value plus an optional source string identifying which collector signal produced it (e.g., "k8s.node.provider", "gpu.smi.gpu.model").
FromMeasurements builds a Fingerprint from a snapshot's measurement slice without taking a dependency on pkg/snapshotter, so the snapshotter can hold a *Fingerprint field and the verifier and bundler packages can consume the type without pulling collectors.
Fingerprint.Match compares a Fingerprint against a recipe.Criteria and returns a structured per-dimension diff with three states: matched, mismatched, or unknown. "Unknown" covers criteria fields the cluster cannot reveal (intent, platform); the overall MatchResult.Matched flag is true so long as no dimension is mismatched, leaving unknown dimensions for human review.
This package is the foundation for ADR-007 verifiable recipe test evidence. The fingerprint and per-dimension diff are recorded in the evidence bundle's predicate body so a maintainer reviewing a contribution can confirm the cluster the recipe was tested on actually matched the recipe's declared criteria.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ParseGPUSKU ¶
ParseGPUSKU normalizes a raw nvidia-smi ProductName string (e.g. "NVIDIA H100 80GB HBM3") to the matching recipe.CriteriaAccelerator enum value (e.g. "h100"). Returns "" when the model does not match any known SKU; callers treat the empty string as "fingerprint did not detect this dimension."
Types ¶
type Dimension ¶
type Dimension struct {
// Value is the resolved dimension value, normalized to the
// matching recipe.Criteria enum where applicable (e.g. "eks",
// "h100", "ubuntu"). Empty string means the dimension was not
// captured.
Value string `json:"value" yaml:"value"`
// Source names the collector signal that produced Value, for
// audit and debugging (e.g. "k8s.node.provider"). Empty when the
// dimension was not captured.
Source string `json:"source,omitempty" yaml:"source,omitempty"`
// Note carries a short audit hint when Value is empty for a
// reason other than missing data — e.g. "multi-region" for a
// region dimension that detected disagreeing labels across
// nodes. The verifier surfaces this in its Markdown rendering so
// "value not captured" and "value deliberately not collapsed"
// stay distinguishable.
Note string `json:"note,omitempty" yaml:"note,omitempty"`
}
Dimension is a single fingerprint dimension. Forward-compatible with ADR-007 V2 extensions: signals[] and confidence are reserved for the follow-on per-signal provenance work and would be added as additional optional fields without a schema break.
type DimensionDiff ¶
type DimensionDiff struct {
// Dimension is the typed dimension name (service, accelerator,
// etc.). Lets consumers filter or look up by name without magic
// strings.
Dimension DimensionName `json:"dimension" yaml:"dimension"`
// RecipeRequires is the criteria value the recipe declares, or
// empty / "any" when the recipe is generic in this dimension.
RecipeRequires string `json:"recipeRequires,omitempty" yaml:"recipeRequires,omitempty"`
// FingerprintProvides is the value the fingerprint resolved for
// this dimension. Empty when the dimension was not captured.
FingerprintProvides string `json:"fingerprintProvides,omitempty" yaml:"fingerprintProvides,omitempty"`
// Match is the three-way outcome.
Match DimensionMatch `json:"match" yaml:"match"`
}
DimensionDiff is a single criteria dimension's comparison outcome.
type DimensionMatch ¶
type DimensionMatch string
DimensionMatch is the three-way per-dimension outcome of Match.
"unknown" means the criteria specifies a value but the fingerprint could not determine it (e.g., recipe intent or platform are recipe-author choices not detectable from cluster state). Unknowns surface in MatchResult.PerDimension for human review without counting as a contradiction in the overall MatchResult.Matched flag.
const ( DimensionMatched DimensionMatch = "matched" DimensionMismatched DimensionMatch = "mismatched" DimensionUnknown DimensionMatch = "unknown" )
type DimensionName ¶
type DimensionName string
DimensionName is a typed criteria dimension key.
const ( DimensionService DimensionName = "service" DimensionAccelerator DimensionName = "accelerator" DimensionOS DimensionName = "os" DimensionIntent DimensionName = "intent" DimensionPlatform DimensionName = "platform" DimensionNodes DimensionName = "nodes" )
DimensionName enumerated values — the criteria dimensions Fingerprint.Match compares. Order here defines the order MatchResult.PerDimension entries are emitted.
type Fingerprint ¶
type Fingerprint struct {
// Service is the Kubernetes service / cloud platform
// (eks, gke, aks, oke, kind, lke). Sourced from
// k8s.node.provider (parsed from spec.providerID).
Service Dimension `json:"service" yaml:"service"`
// Accelerator is the GPU SKU (h100, gb200, b200, a100, l40,
// rtx-pro-6000). Parsed from gpu.smi.gpu.model.
Accelerator Dimension `json:"accelerator" yaml:"accelerator"`
// OS is the worker node operating system, with the raw
// VERSION_ID retained for audit. Sourced from
// os.release.{ID,VERSION_ID}.
OS OSDimension `json:"os" yaml:"os"`
// K8sVersion is the Kubernetes server version with the leading
// "v" stripped (e.g., "1.33.4"). Sourced from k8s.server.version.
K8sVersion Dimension `json:"k8sVersion" yaml:"k8sVersion"`
// Region is the cluster region (e.g., "us-west-2"). Sourced from
// the topology.kubernetes.io/region node label aggregated by the
// topology collector. Omitted when the cluster has no consistent
// region label or spans multiple regions.
Region Dimension `json:"region,omitempty" yaml:"region,omitempty"`
// NodeCount is the total number of cluster nodes including
// control-plane and worker nodes. Sourced from
// nodeTopology.summary.node-count. For "how many GPU workers"
// see GPUNodeCount.
NodeCount IntDimension `json:"nodeCount" yaml:"nodeCount"`
// GPUNodeCount is the number of nodes carrying the GPU operator's
// nvidia.com/gpu.product label (the canonical "this node has a
// GPU" signal). Zero on clusters without the GPU operator
// installed. Sourced from the topology label subtype.
GPUNodeCount IntDimension `json:"gpuNodeCount" yaml:"gpuNodeCount"`
}
Fingerprint is the structured cluster identity at snapshot time. Per ADR-007 it is the input the verifier uses to confirm a recipe's criteria matched the cluster on which validate ran.
func FromMeasurements ¶
func FromMeasurements(measurements []*measurement.Measurement) *Fingerprint
FromMeasurements builds a Fingerprint from a snapshot's measurement slice. Dimensions whose source signal is missing keep their zero value (empty string for Dimension/OSDimension, 0 for IntDimension); callers compare those against criteria using Match, which treats missing fingerprint values as "unknown" rather than "mismatched."
func (*Fingerprint) Match ¶
func (f *Fingerprint) Match(c *recipe.Criteria) MatchResult
Match compares the fingerprint against a recipe's criteria and returns a per-dimension diff plus an overall Matched flag.
Per-dimension semantics:
- Recipe value is empty / "any" → matched (recipe is generic).
- Recipe value is specific, fingerprint did not capture → unknown (the fingerprint cannot prove a match, but cannot disprove one either).
- Recipe value is specific, fingerprint captured the same value → matched.
- Recipe value is specific, fingerprint captured a different value → mismatched.
Overall Matched is true when no dimension is mismatched. Unknown dimensions surface in PerDimension for human review without flipping the overall outcome.
Criteria fields that the cluster cannot reveal — Intent and Platform — are reported as unknown when the recipe declares a specific value, and matched when the recipe is generic. The fingerprint deliberately does not attempt to fabricate them.
A nil criteria pointer is treated as a fully-generic recipe: every dimension is matched and the overall result is matched=true.
func (*Fingerprint) ToCriteria ¶
func (f *Fingerprint) ToCriteria() *recipe.Criteria
ToCriteria projects the fingerprint into a recipe.Criteria so the recipe builder can match against a captured cluster (the `aicr recipe --snapshot` flow). Dimensions the fingerprint did not resolve become "any" via the recipe package's enum parsers — a fingerprint with no accelerator detected yields a generic Criteria that matches recipes pinning any accelerator.
Intent and Platform are recipe-author choices the cluster cannot reveal, so they always come back as "any"; callers wanting to drive recipe selection by intent or platform must layer that on top of ToCriteria from the CLI flag side.
type IntDimension ¶
type IntDimension struct {
// Value is the resolved integer value. Zero indicates the
// dimension was not captured.
Value int `json:"value" yaml:"value"`
// Source names the collector signal that produced Value.
Source string `json:"source,omitempty" yaml:"source,omitempty"`
}
IntDimension is a fingerprint dimension whose resolved value is an integer (e.g., node count).
type MatchResult ¶
type MatchResult struct {
Matched bool `json:"matched" yaml:"matched"`
PerDimension []DimensionDiff `json:"perDimension" yaml:"perDimension"`
}
MatchResult is the structured outcome of Fingerprint.Match.
Matched is true when no dimension is Mismatched. Unknown dimensions (e.g., criteria.intent / criteria.platform when the fingerprint does not capture them) do not flip Matched to false: they surface in PerDimension for the maintainer to evaluate, but the fingerprint itself cannot disprove a match it does not capture.
PerDimension is an ordered slice so iteration is deterministic and serialization is stable. Use Find for lookup by name.
func (MatchResult) Find ¶
func (r MatchResult) Find(name DimensionName) (DimensionDiff, bool)
Find returns the diff for the named dimension. The second return is false when no entry exists for that dimension (impossible today; future evolutions might add or omit dimensions).
type OSDimension ¶
type OSDimension struct {
Value string `json:"value" yaml:"value"`
Version string `json:"version,omitempty" yaml:"version,omitempty"`
Source string `json:"source,omitempty" yaml:"source,omitempty"`
}
OSDimension extends Dimension with the raw OS version string. Value is the criteria-aligned OS kind (ubuntu, rhel, cos, amazonlinux, talos); Version carries the unmodified VERSION_ID from /etc/os-release for audit purposes (recipe.Criteria has no version field, so Version does not participate in Match).