| index 55fc89614..dcf806114 100644 |
| --- a/CLAUDE.md |
| +++ b/CLAUDE.md |
| @@ -75,6 +75,19 @@ deliver or verify its result. |
| - **Adoption swaps a symlink; it does not restart processes.** Order is: |
| promote → adopt → restart. Long-running units (console, keymail relay) need |
| the restart; hibernating tenants pick it up on wake. |
| +- **A route's Channel and Environment belong to its instance record** once the |
| + route is `Provisioned` (main, 2026-08-10). The provisioning reconciler |
| + converges both from `apps/<sqid>/<app>/instances/<host>.json` on every pass, |
| + so a `carlos route -channel` on the box lands and is reverted within seconds |
| + of the next serial bump — `carlos route` refuses both axes on such a row and |
| + names the record. Reconcile also ADOPTS an existing route whose shape matches |
| + an appearing record, which is how the fleet gets backfilled with no box |
| + commands. Adoption stamps `Provisioned`, and `Provisioned` is the ONE |
| + condition the removal phase keys on — so adoption is an authority transfer, |
| + and the shape match is what stands between a backfill and a retired |
| + production route. It refuses any row carrying a column the record cannot |
| + express (`Backing`, `Tunnel`, `Caps`) or owned by another pass (`Platform`, |
| + `Canary`). |
| - **Console security gates are ordered**: session → CSRF → owner (byte-identical |
| 404) → `requireFreshAuth` LAST. A non-member must never get a redirect that |
| confirms an account exists. |