Billing polish follow-ups
Follow-ups found while doing Task 8561 (the plans, customers and tenant billing polish). Each item is a short requirement:
1. Console open: run the Agents/Active worktrees cap check and the `user` claim in ONE locked transaction (`org_limits.require_headroom` + `slot_state.claim_for_user`). Today `routes/console.py::_worktree_cap_refusal` counts with no lock and no staging-family fleet session, so concurrent opens can go past the cap.
2. Customers › Billing › Details (`DeskDetailsEditor`): switching the `?billing=` sub-tab or the customer `?tab=` with unsaved edits drops them silently. `useLeaveGuard` only catches leaving the path, so guard the tab switch as well.
3. Docs screenshot `apps/docs/content/administration/plan-and-billing/img/subscription/limits.png` still shows "Agents". Retake it so it shows "Agents active".
4. Sign-up summary on a phone: long values ("Signed up", "Approved", "Applicant") drop below their label while short ones sit beside it. Use one rule, either always stacked or always beside, so the column reads evenly.
5. Customer Plan tab with billing not connected: the tab no longer names Stripe anywhere. Show the Connect Stripe caption once at the Terms heading, as Products › Plans does.
6. Same-name chip on Products › Plans names the other plan only on hover. Name it in the visible line on wide screens ("Same name as team_trial").
Out of scope: prices, trial logic, the purchase API, Stripe sync.
Done means:
- Each item is fixed, or declined with a one-line reason in the PR.
- Item 1 has a test where two concurrent opens at cap−1 yield exactly one session.
Outcome
Fixed 5 of 6 items in PR #6514: console cap check and claim now run under one lock, before the node opens; the details editor guards tab switches; plus the phone, Stripe-caption and same-name UI fixes. Item 3 (screenshot) declined: change not on prod, draft #8655 filed. Merged; deploy succeeded; visual check done.
Artifacts
Activity
- Created
- Run
- Runner started
- Runner ended (done)