---
id: w1/m8/t004
title: "Tier the legacy bare-CR apps + end-to-end verify (limits on pods, percentage metrics live) + docs"
worker: worker1
status: done
estimate: 30m
depends_on: [w1/m8/t002, w1/m8/t003]
---

## Objective

Close the user-visible gap: the untiered legacy apps (bare CRs created before the control plane — prod's `beancount-cms` is the known case) get a tier via the new plan verb, and the payoff is proven live — pods carry requests==limits and the metrics page's Percentage tab shows 0–100 charts with a "Limit …" label where it said "No limit configured — percentage is undefined".

## Context

- **Store-managed apps need nothing here** — `normalizeTier` already defaults empty→`free` and the projector already writes `spec.tier` (`reconciler.go:184,211`). The gap is exactly the apps with no row.
- Fix mechanism: the t003 plan-change verb (CR-patch path) — no migration/backfill machinery needed. Survey untiered apps first (`kubectl get apps.app.bex.co -A -o custom-columns=NAME:.metadata.name,TIER:.spec.tier`).
- Tier choice for `beancount-cms`: pick by its observed usage (w3/m4.5 showed ~420MiB working set — `free`/`starter` at 512Mi is tight; `standard` 2Gi is the safe call). Setting it rolls the pod once.
- Verification: after the roll, `kubectl get pod -o yaml` shows requests==limits; the prod (or tunnel-dev) metrics page shows Percentage charts + "Limit …" label; the `*_LIMIT` metrics need no changes (they read pod-spec limits).
- Docs: `docs/ADR003-control-plane.md` §Tiers table becomes a pointer to `lego/types/tiers/tiers.yaml` (keep the prose, drop the duplicated numbers); `docs/ADR010-observability.md`'s no-limit deviation note now applies only to untiered bare-CR apps. Prettier after.

## Steps

1. Survey untiered apps; set plans via the new verb (beancount-cms ⇒ standard, judged against its live memory usage).
2. Verify live: pod limits present; metrics page Percentage tab + limit label rendering real values.
3. Docs updates; `npx prettier@3.4.2 --write "**/*.md"`.

## Files

- `docs/ADR003-control-plane.md`, `docs/ADR010-observability.md` (no code expected)

## Acceptance criteria

- [ ] No user-facing App on the cluster reports an empty `plan`.
- [ ] Live metrics page for `beancount-cms`: Percentage tab shows 0–100 charts + "Limit …" label; "No limit configured" gone.
- [ ] Docs carry one ladder (the YAML) and a pointer, not a second copy; prettier clean.

## Out of scope

- Dashboard plans page; free-tier idle semantics (w1/m4); automated adoption of bare CRs into the store.
