diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx index 7626c0fd..c1a67354 100644 --- a/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx +++ b/src/apps/officer-web/Screens/Dashboard/Layout/Dock.tsx @@ -174,6 +174,10 @@ export const CORE_DOCK_ITEMS: DockItem[] = [ { label: 'Monitor', to: '/system-monitor', icon: Activity, color: '#0ea5e9' }, { label: 'Activity', to: '/activity', icon: Radio, color: '#f59e0b' }, { label: 'Dashboards', to: '/dashboards', icon: LayoutGrid, color: '#8b5cf6' }, + // Core because the tailnet is the perimeter — origin checking was removed on the grounds that the + // tailnet stands in its place, so administering it cannot be an optional extra. It is `kind: 'admin'`, + // and DashboardLayout filters every tile through canVisit(), so a member never sees this one. + { label: 'Headscale', to: '/headscale', icon: Network, color: '#818cf8' }, // Core by necessity: the store is how every other feature arrives, so it can never be one of the // things that disappears when uninstalled. { label: 'App store', to: '/app-store', icon: Store, color: '#64748b' }, diff --git a/src/servers/app-store/catalogue.ts b/src/servers/app-store/catalogue.ts index cffe09e2..b1aefeb9 100644 --- a/src/servers/app-store/catalogue.ts +++ b/src/servers/app-store/catalogue.ts @@ -359,22 +359,18 @@ export const CATALOGUE: CatalogueEntry[] = [ }, ], }, - { - id: 'headscale', - ui: { name: 'Headscale', icon: 'Network', color: '#818cf8', rootRoute: '/headscale', routes: ['/headscale'] }, - process: 'officer-headscale', - label: 'Headscale', - summary: 'Your own tailnet control plane', - members: 'none', - modes: ['existing'], - capability: 'headscale', - // A member enrolling their own device is the same sidecar. See `alsoServes`. - alsoServes: ['vpn'], - existingFields: [ - { key: 'url', label: 'Headscale URL', type: 'url', required: true }, - { key: 'secret', label: 'API key', type: 'secret', required: true }, - ], - }, + // Headscale was here until 2026-08-14 and is CORE now — `officer-headscale` runs in the baseline + // profile, so it is not something you install, and `catalogue.test.ts` had been failing on exactly + // that ("does not offer to install the baseline") since it was promoted. + // + // Leaving it here did more than fail a test. Availability is derived ONLY from `sidecar_installs`, + // and a core sidecar never gets a row there — so `headscale` and `vpn` were permanently `unavailable`, + // which withheld the dock manifest AND put /headscale into `deniedRoutes`. The screen was unreachable + // and invisible on a server where the sidecar was up and healthy. + // + // Its tile is in CORE_DOCK_ITEMS instead, and servers are configured where they always really were — + // the Servers view inside the app, which is why the `existingFields` here were a redundant second + // place to type the same URL and API key. // ── Nothing to reach: configuration only ─────────────────────────────────────────────────────────── {