carlos / platform Public
| Earlier finding | Disposition at 726660f2 | |---|---| | R4.1 — Recovery bypasses the empty-bucket safeguard | Fixed: §2 applies the shared tripwire to absence-based finalization. | | R4.2 — Trash UI/API promises 30 days | Fixed: §5 specifies one effective deadline for all displays and responses. | | 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. | | R5.2 — Expiry markers defeat the empty-bucket tripwire | Fixed: a tripped pass writes nothing, and markers do not count as bucket evidence. |
- P1 — §3: checking the console’s registry does not protect permanent services on another box.
The proposed account-scoped appHasRoutes still reads only s.cfg.Registry (appsettings.go:711). The existing apex check explicitly documents that hand-added routes on another box are invisible (apex.go:74).
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, agent.go:2257). The temporary app’s tombstone then deletes the permanent service’s route (reconcile.go:206).
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.
- P1 — §3: the account predicate differs from the ownership rules applied before route deletion.
The new check matches release.RouteAccount(rt), which returns the current valid account or falls back to ops (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, reconcile.go:735).
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), making B the sole bucket owner. Reconciliation stamps the existing service’s route as B before evaluating trash removal (reconcile.go:189). B’s expiry therefore removes A’s permanent service.
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.
Verdict: revise.