---
id: w1/m2/t005
title: Reconciler — project `apps` rows into `App` CRs
worker: worker1
status: done
estimate: 30m
depends_on: [w1/m2/t003]
---

## Objective

Close the loop from source of truth to runtime: a control-plane reconcile loop turns `apps` rows (+ their primary `domains` row) into `App` CRs (create/update/delete), setting `spec.host`/`spec.tier`. The operator does the rest.

## Context

- `App` CR is the contract (see `docs/ADR003-control-plane.md` request-flow). The control plane writes intent; the operator executes.
- Reconcile on row change; delete the CR when the row is deleted.

## Steps

1. Map an `apps` row (+ primary domain) → an `App` object with `spec.host`/`spec.tier`.
2. Create/update/delete via the k8s API; requeue on drift.

## Files

- `operator/internal/controlplane/reconciler.go`

## Acceptance criteria

- [ ] Inserting an `apps` row causes a matching `App` CR to appear; deleting the row removes the CR.

## Out of scope

- The HTTP API that inserts rows (t006).
