Skip to content

feat(aicr): wrap facade alias types as facade-owned structs #1078

Description

@mchmarny

Summary

Replace the transparent type aliases in types.go:32-59 (Snapshot, AgentConfig, PhaseResult, Phase, and the phase constants) with facade-owned structs and translate at the boundary — same pattern ValidateOption already uses in options.go:24.

Motivation

docs/integrator/public-api.md advertises github.com/NVIDIA/aicr as Public (stable) and marks pkg/snapshotter as Internal ("may change without notice"). But types.go:32 is type Snapshot = snapshotter.Snapshot — a transparent type alias. Consumers using aicr.Snapshot are identity-pinned to snapshotter.Snapshot; any field rename/removal in the "Internal" package breaks them.

Same shape for AgentConfig (types.go:40, ← snapshotter), PhaseResult (line 46), Phase (line 51), and the phase constants (lines 55-59). pkg/validator is "Public (evolving)" not "Internal" but it still can't supply identity for a "stable" surface — "evolving" by definition admits minor-bump breakage.

The PR description (#1072) acknowledges this: "promoting them to facade-owned wrappers is worth scoping separately."

Acceptance

  • aicr.Snapshot, aicr.AgentConfig, aicr.PhaseResult, aicr.Phase, and the phase constants are facade-owned types with no transparent alias to internal packages.
  • Translation between facade types and pkg/snapshotter / pkg/validator types is done inside the facade (analogous to applyValidateOptions in options.go).
  • docs/integrator/public-api.md is consistent: every type reachable from the Public (stable) facade is either facade-owned or comes from a package the matrix lists as Public (stable).
  • No regression in facade tests; CLI/REST behavior unchanged.

Notes on translation cost

Most of these types carry transitively-referenced types of their own (e.g., validator.PhaseResult embeds a CTRF report; snapshotter.Snapshot embeds a measurement.Measurement slice). The fix has to either:

  1. Wrap the immediate type and re-expose only the fields the facade guarantees (lossy but stable), or
  2. Wrap recursively (high effort, mirrors more types).

Pick (1) unless a consumer concretely needs a field that (1) drops.

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions