---
id: w2/m7/t010
title: Closeout
worker: worker2
status: todo
estimate: 10m
depends_on: [w2/m7/t009]
---

## Objective

Close the milestone once the Definition of Done actually holds against a real cluster. **Implementation, tests, parity, and simplify (t001–t009) are complete and green** (`go test ./...`, `make lint-backend` 0 issues, operator suspend/resume envtest) as of 2026-07-09.

**Live-confirmed against the prod app-cluster (2026-07-09, no deploy needed)** via the gated `TestKeyValueLiveIntegration` (`internal/keyvalue/keyvalue_live_test.go`, run with `BEX_TEST_KUBECONFIG=<app.kubeconfig>`, skipped in CI):

- The **actual bex-api Go verbs** against the live cluster + operator: `CreateKeyValue` (public) → operator reconcile `creating`→`available` (~34s) → `KeyValueConnectionInfo` returned `redis://…m7-live.default.svc:6379` (internal) **and** `rediss://…@m7-live.kv.bex.co:6379` (external), with `cliCommand` over the TLS endpoint and no standalone password field → `DeleteKeyValue` → gone. Create / List / Get / ConnectionInfo(internal+external) / Delete all proven live.
- Plus the earlier w1/m14 operator verification: create → Ready → PING/SET/GET → delete cascade.

**The one item still gated on `/ship` → CI → Argo deploy:**

- **Suspend/resume scale-to-zero.** Needs the new operator + regenerated CRD (`spec.suspended`); prod runs `e6372a1`, whose CRD prunes the field, so the live scale can't be exercised until the deploy. The mechanism is proven by the operator envtest against a real apiserver (0↔1 replicas, Secret/password preserved). A manual operator deploy was ruled out — it would fight Argo auto-sync and needs an image push (CI's job).
- _(Not a code gap:)_ the pure HTTP-transport + auth-gate smoke couldn't run locally because the app-cluster node's **kubelet TLS is currently broken** (`kubectl port-forward`/`exec` → `tls: internal error`), so Hydra is unreachable from the laptop. That layer is unit-tested across all three adapters; the live integration above drives the verbs through the API server directly, which works.

After the next `/ship` + deploy: confirm `suspend`/`resume` scales the StatefulSet 0↔1 on prod (REST + GraphQL), then this task _is_ the move to `done/`.

## Context

- `.pm/CLAUDE.md`: tasks → `done/`, README rows `— **DONE**` + `**Status:** done`, milestone dir → `w2/done/m7/`, workstream checkbox. Also retire the promoted inbox note `w2/003.md` → `w2/done/003.md` if not already moved at materialization time.

## Steps

1. Re-verify the DoD live (mock cluster or prod).
2. Flip statuses, move files, move the milestone whole, check the box.

## Files

- `.pm/w2/m7/**`, `.pm/w2/README.md`

## Acceptance criteria

- [ ] DoD verified before any flip; all three status locations in sync; no tombstone at the old path.

## Out of scope

- Any implementation.
