Parked work from closed PR #146.
Problem
CF Access dashboard accumulates dead `dd-*` self-hosted apps every time a tunnel gets torn down outside the collector's orphan-GC path: force-deleted preview VMs, apps from old naming schemes, the tail of long preview cycles. Dozens of stale apps pile up over time.
Shape
New `cf::reap_orphan_access_apps(env)`:
- List every `dd-{env}-*` Access app.
- For each, extract the base hostname from `domain` (strip any `/path`).
- Look up that hostname's CNAME → target tunnel id (`.cfargotunnel.com`).
- Cross-reference against the live `cf::list` tunnel set.
- Delete apps whose target tunnel is gone or whose CNAME no longer exists.
CNAME lookups cache per base hostname (many apps share a host via path-scoped bypasses). Best-effort: delete failures log and continue.
CP's `run()` spawns it 10s after startup as a fire-and-forget task so a slow CF API call doesn't block the collector or agent registration. Every CP deploy becomes a cleanup pass.
Why we closed the PR
Noise-to-value ratio for reviewing it right now wasn't worth it. Re-open when the CF dashboard clutter becomes annoying enough.
Parked work from closed PR #146.
Problem
CF Access dashboard accumulates dead `dd-*` self-hosted apps every time a tunnel gets torn down outside the collector's orphan-GC path: force-deleted preview VMs, apps from old naming schemes, the tail of long preview cycles. Dozens of stale apps pile up over time.
Shape
New `cf::reap_orphan_access_apps(env)`:
CNAME lookups cache per base hostname (many apps share a host via path-scoped bypasses). Best-effort: delete failures log and continue.
CP's `run()` spawns it 10s after startup as a fire-and-forget task so a slow CF API call doesn't block the collector or agent registration. Every CP deploy becomes a cleanup pass.
Why we closed the PR
Noise-to-value ratio for reviewing it right now wasn't worth it. Re-open when the CF dashboard clutter becomes annoying enough.