fingerprint

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: May 15, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

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

func ParseGPUSKU(model string) string

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).

Jump to

Keyboard shortcuts

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