# 0004. Phase 1 creates three kinds, not seven

Status: Accepted · Date: 2026-10-25 · Design section: 4.1, 4.2, roadmap item 1

Decided: Phase 1 scaffolds only `TalosCluster`, `TalosMachine` and `TalosConfigPatch`, with no controllers yet

## Context

The API table lists seven kinds. Roadmap item 1 asks for "CRDs and the
kubebuilder project, Helm chart and Kustomize base, deletion protection, e2e
scaffolding", without saying which kinds, and the phase ordering puts
`TalosEtcdBackup` in phase 5, `TalosOperation` and `IchorInstallation` in
phase 6 and `TalosStorage` in phase 7.

Creating a kind costs one `kubebuilder create api` call and is additive, so
nothing is saved by creating all seven now. Guessing their *fields* is what
costs: anything published in `v1alpha1` has to keep working, and a field no
code reads yet is a field whose shape nothing has tested.

## Decision

Phase 1 creates the three kinds the next two phases actually work on —
`TalosCluster`, `TalosMachine`, `TalosConfigPatch` — with
`--resource=true --controller=false`, since reconcilers are phase 2.
`TalosStorage`, `TalosEtcdBackup`, `TalosOperation` and `IchorInstallation` are
created in the phase that gives them behaviour.

Within those three, phase 1 defines only the fields phases 1 to 3 need. Later
phases add their own, which is backwards compatible within `v1alpha1`.
Deferred for now: `documents[]` and `defaultsRule` (phase 2 and 3, see ADR
0003), `disks[]` / `systemDiskLayout` / `forceRemove` / `upgradeHold` (phase
3), `cni` and `gitops` (phase 4), `upgradeStrategy` (phase 6), `monitoring` /
`components[]` / `integrations[]` (phase 9), `images` (phase 10).

Three field-level decisions that the design leaves open:

- **`versionContract` is required**, not defaulted. Principle 4 pins the
  version contract in the CR so that a machinery bump cannot change what gets
  applied. If the field were optional and resolved at reconcile time, a bump
  would do exactly that. Requiring it needs no webhook; a defaulting webhook
  that fills it from `talosVersion` at creation can relax this later without
  breaking anyone.
- **`TalosMachine.spec.nodeLabels`**, not `labels`. The design calls it
  `labels`; inside a spec that reads as "labels on this object", when what is
  meant is labels to put on the Kubernetes Node.
- **`layer` cannot be set to `system`.** The system layer is generated by
  Ichor, so the enum offers `cluster`, `role`, `selector` and `machine` only,
  and the schema rejects the rest rather than a webhook having to.

## Consequences

- Phase 1 ships a small, complete API instead of a large, speculative one, and
  the chart's CRD set grows one kind at a time as the phases land.
- A kind's fields get designed next to the code that reads them, so the
  acceptance criteria for each phase can actually check the shape.
- The cost is that `kubectl get crd` won't show the full catalogue until phase
  7. The API table in the design doc remains the place to see where it's going.

- Update: `IchorInstallation` was created in phase 6 with ADR 0059.
