| 1 | | Earlier finding | Disposition at `726660f2` | |
| 2 | |---|---| |
| 3 | | R4.1 — Recovery bypasses the empty-bucket safeguard | **Fixed:** §2 applies the shared tripwire to absence-based finalization. | |
| 4 | | R4.2 — Trash UI/API promises 30 days | **Fixed:** §5 specifies one effective deadline for all displays and responses. | |
| 5 | | R5.1 — Route-only permanent service can be claimed temporary | **Not fixed completely:** the new check misses remote routes and routes whose account reconciliation changes. New counterexamples below also leave inherited R1.2 unresolved. | |
| 6 | | R5.2 — Expiry markers defeat the empty-bucket tripwire | **Fixed:** a tripped pass writes nothing, and markers do not count as bucket evidence. | |
| 7 | |
| 8 | 1. **P1 — §3: checking the console’s registry does not protect permanent services on another box.** |
| 9 | |
| 10 | The proposed account-scoped `appHasRoutes` still reads only `s.cfg.Registry` ([appsettings.go:711](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/console/appsettings.go:711)). The existing apex check explicitly documents that hand-added routes on another box are invisible ([apex.go:74](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/console/apex.go:74)). |
| 11 | |
| 12 | Put a permanent, route-only service on platform box B, with the console on box A. Its account/app prefixes and console row are absent. A successfully reads its own registry, finds nothing, and permits temporary creation using that identity. When B holds the housekeeper lease, it runs domains reconciliation against its own registry ([agent.go:2238](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/host/agent.go:2238), [agent.go:2257](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/host/agent.go:2257)). The temporary app’s tombstone then deletes the permanent service’s route ([reconcile.go:206](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/domains/reconcile.go:206)). |
| 13 | |
| 14 | **Fix:** require authoritative deployment-wide route inventory before granting temporary status. Refuse when coverage cannot be established; a successful local registry read is insufficient. Add a two-registry test with the permanent service on the non-console housekeeper. |
| 15 | |
| 16 | 2. **P1 — §3: the account predicate differs from the ownership rules applied before route deletion.** |
| 17 | |
| 18 | The new check matches `release.RouteAccount(rt)`, which returns the current valid account or falls back to ops ([adopt.go:862](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/release/adopt.go:862)). However, domains reconciliation can replace even an explicitly assigned account when that account has no objects and another account is the sole bucket owner of the app name ([reconcile.go:723](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/domains/reconcile.go:723), [reconcile.go:735](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/domains/reconcile.go:735)). |
| 19 | |
| 20 | A permanent TCP service named `report` belongs to account A and has no bucket objects. Account B creates temporary `report`. The proposed account-scoped check permits it. Creation normally writes B’s default pipeline ([server.go:3570](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/console/server.go:3570)), making B the sole bucket owner. Reconciliation stamps the existing service’s route as B **before** evaluating trash removal ([reconcile.go:189](/home/paulca/amadan.net/carlos/platform/.claude/worktrees/temporary-sites/internal/domains/reconcile.go:189)). B’s expiry therefore removes A’s permanent service. |
| 21 | |
| 22 | **Fix:** check prospective reconciliation ownership, not just the route’s current account. Refuse temporary creation if introducing that account/app prefix would cause an existing same-name route to be adopted. Test both an explicitly different account and an unstamped route, with no objects under the permanent service’s prefix. |
| 23 | |
| 24 | Verdict: **revise**. |