switch off every plugin router, pending extraction
Twelve capabilities unmounted: gitea, music, photos, jellyfin, memos, calendar,
email, notify, transmission, soulseek, invoices, wallet. Mounts commented in
place, implementation untouched on disk, same as vault and the browser relay.
Each needed its capability's `api` claim commented in the same change.
assertCapabilityTotality check 2 refuses to boot on a capability claiming a
prefix nothing mounts, so unmounting alone would have stopped the server
starting — the opposite of what happened with vault, which is exempt.
music also claims two websockets. Its `ws: ['cliamp', 'cliamp-audio']` claim, the
two handlers in server.tsx and the provider union entries all had to move
together: check 3 fails on a served socket nothing claims, check 4 on a claimed
socket nothing serves.
calendar was the awkward one and the mount list was not where it lived. Four of
its six doors are not in the routes table:
honoServer.route('/dav', davSyncRouter) the sync door, top-level, not /api
honoServer.all('/.well-known/caldav') RFC 6764 autodiscovery
honoServer.all('/.well-known/carddav') the same for contacts
four routes in server.tsx /dav, /dav/*, and both well-knowns
and the two that ARE in the table carry trailing comments, which is why the first
pass silently missed them and left /api/caldav and /api/dav mounted with their
claim gone — exactly the boot failure this commit is about.
/vpn deliberately stays. It reads as a plugin (kind 'app') but it is OffTail
enrollment forwarding to officer-headscale, which is core because the tailnet is
the perimeter.
Verified by simulating assertCapabilityTotality against the post-change files
rather than trusting the edits: parse hono's live mounts, the registry's live
claims, server.tsx's live ws providers and totality's two exempt lists, then run
all four checks. It reported the two stale caldav mounts, which is how they were
found. Zero problems now, 34 live mounts, all core.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+30
-30
@@ -19,27 +19,27 @@ import { uploadRouter } from './api/upload/upload';
|
||||
import { settingsRouter } from './api/settings/settings';
|
||||
import { dashboardsRouter } from './api/dashboards';
|
||||
import { router as fileBrowserRouter } from './api/file-browser/router';
|
||||
import { musicRouter } from './api/music/router';
|
||||
// import { musicRouter } from './api/music/router';
|
||||
// import { vaultRouter } from './api/vault/router';
|
||||
// import { publicVaultRouter, VAULT_ONLY_PREFIXES, isBitwardenClient } from './api/vault/public-router';
|
||||
import { agentHandoffRouter } from './api/agent-handoff/router';
|
||||
import { slskdRouter } from './api/slskd/router';
|
||||
// import { slskdRouter } from './api/slskd/router';
|
||||
import { headscaleRouter } from './api/headscale/router';
|
||||
import { transmissionRouter } from './api/transmission/router';
|
||||
import { invoiceshelfRouter } from './api/invoiceshelf/router';
|
||||
import { jellyfinRouter } from './api/jellyfin/router';
|
||||
import { photosRouter } from './api/photos/router';
|
||||
import { walletRouter } from './api/wallet/router';
|
||||
// import { transmissionRouter } from './api/transmission/router';
|
||||
// import { invoiceshelfRouter } from './api/invoiceshelf/router';
|
||||
// import { jellyfinRouter } from './api/jellyfin/router';
|
||||
// import { photosRouter } from './api/photos/router';
|
||||
// import { walletRouter } from './api/wallet/router';
|
||||
import { vpnRouter } from './api/vpn/router';
|
||||
import { terminalRouter } from './api/terminal/sidecar-server';
|
||||
import { caldavRouter } from './api/dav/sidecar-server';
|
||||
import { memosRouter } from './api/memos/router';
|
||||
import { giteaRouter } from './api/gitea/router';
|
||||
// import { caldavRouter } from './api/dav/sidecar-server';
|
||||
// import { memosRouter } from './api/memos/router';
|
||||
// import { giteaRouter } from './api/gitea/router';
|
||||
import { appStoreRouter } from './api/app-store/router';
|
||||
import { davSyncRouter } from './api/dav/sync-router';
|
||||
import { davRouter } from './api/dav/router';
|
||||
// import { davSyncRouter } from './api/dav/sync-router';
|
||||
// import { davRouter } from './api/dav/router';
|
||||
import { claimIosProfile } from './api/dav/ios-profile';
|
||||
import { notifyRouter } from './api/notify/router';
|
||||
// import { notifyRouter } from './api/notify/router';
|
||||
import { systemMonitorRouter } from './api/system-monitor/system-monitor';
|
||||
import { activityRouter } from './api/activity/router';
|
||||
// Vault still hand-rolls its port capture, so it keeps a side-effect import; every other HTTP sidecar
|
||||
@@ -48,7 +48,7 @@ import { activityRouter } from './api/activity/router';
|
||||
import { dockRouter } from './api/dock/dock';
|
||||
import { integrationsRouter, googleCallbackHandler } from './api/integrations/integrations';
|
||||
import { queueRouter } from './api/queue/queue';
|
||||
import { emailRouter } from './api/email/router';
|
||||
// import { emailRouter } from './api/email/router';
|
||||
// The browser relay is switched off — see server.tsx. Restoring this mount means restoring the
|
||||
// registry's claim on '/browser' in the same commit, or assertCapabilityTotality refuses to boot.
|
||||
// import { browserRouter } from './api/browser/router';
|
||||
@@ -158,7 +158,7 @@ honoServer.get('/dav/provision/:file', (ctx) => {
|
||||
});
|
||||
});
|
||||
|
||||
honoServer.route('/dav', davSyncRouter);
|
||||
// honoServer.route('/dav', davSyncRouter); // plugin — switched off 2026-08-13
|
||||
|
||||
// Autodiscovery. This is most of what makes adding an account on a phone feel transparent instead of
|
||||
// fiddly: the client is given a bare domain and probes these paths UNAUTHENTICATED before it has any
|
||||
@@ -168,8 +168,8 @@ honoServer.route('/dav', davSyncRouter);
|
||||
// `.all`, not `.get`: RFC 6764 §6 has the client probe the well-known URI with the method it actually
|
||||
// wants to use, and iOS sends PROPFIND, not GET. Registered as GET-only these answered 404 to every real
|
||||
// client while looking perfectly healthy in a browser.
|
||||
honoServer.all('/.well-known/caldav', (ctx) => ctx.redirect('/dav/', 301));
|
||||
honoServer.all('/.well-known/carddav', (ctx) => ctx.redirect('/dav/', 301));
|
||||
// honoServer.all('/.well-known/caldav', (ctx) => ctx.redirect('/dav/', 301));
|
||||
// honoServer.all('/.well-known/carddav', (ctx) => ctx.redirect('/dav/', 301));
|
||||
|
||||
const protectedRouter = createRouter();
|
||||
protectedRouter.use(bodyParser());
|
||||
@@ -199,28 +199,28 @@ const PROTECTED_MOUNTS: [prefix: string, router: ReturnType<typeof createRouter>
|
||||
['/api-keys', apiKeysRouter], // your own keys; the `account` core capability covers it
|
||||
['/dashboards', dashboardsRouter],
|
||||
['/file-browser', fileBrowserRouter],
|
||||
['/music', musicRouter],
|
||||
['/slskd', slskdRouter],
|
||||
// ['/music', musicRouter], // plugin — switched off 2026-08-13
|
||||
// ['/slskd', slskdRouter], // plugin — switched off 2026-08-13
|
||||
['/terminal', terminalRouter],
|
||||
['/memos', memosRouter],
|
||||
['/gitea', giteaRouter],
|
||||
// ['/memos', memosRouter], // plugin — switched off 2026-08-13
|
||||
// ['/gitea', giteaRouter], // plugin — switched off 2026-08-13
|
||||
['/app-store', appStoreRouter],
|
||||
['/caldav', caldavRouter], // the JSON door for Officer's own calendar/contacts UI
|
||||
['/dav', davRouter], // app-password management (the sync door is /dav, top-level)
|
||||
['/notify', notifyRouter],
|
||||
// ['/caldav', caldavRouter], // the JSON door for Officer's own calendar/contacts UI — plugin, switched off 2026-08-13
|
||||
// ['/dav', davRouter], // app-password management (the sync door is /dav, top-level) — plugin, switched off
|
||||
// ['/notify', notifyRouter], // plugin — switched off 2026-08-13
|
||||
['/headscale', headscaleRouter],
|
||||
['/transmission', transmissionRouter],
|
||||
['/invoiceshelf', invoiceshelfRouter],
|
||||
['/jellyfin', jellyfinRouter],
|
||||
['/photos', photosRouter],
|
||||
['/wallet', walletRouter],
|
||||
// ['/transmission', transmissionRouter], // plugin — switched off 2026-08-13
|
||||
// ['/invoiceshelf', invoiceshelfRouter], // plugin — switched off 2026-08-13
|
||||
// ['/jellyfin', jellyfinRouter], // plugin — switched off 2026-08-13
|
||||
// ['/photos', photosRouter], // plugin — switched off 2026-08-13
|
||||
// ['/wallet', walletRouter], // plugin — switched off 2026-08-13
|
||||
['/vpn', vpnRouter],
|
||||
['/system-monitor', systemMonitorRouter],
|
||||
['/activity', activityRouter],
|
||||
['/dock', dockRouter],
|
||||
['/integrations', integrationsRouter],
|
||||
['/queue', queueRouter],
|
||||
['/email', emailRouter],
|
||||
// ['/email', emailRouter], // plugin — switched off 2026-08-13
|
||||
// ['/browser', browserRouter], // switched off — see server.tsx
|
||||
['/bug-report', bugReportRouter],
|
||||
['/agent-status', agentStatusRouter],
|
||||
|
||||
Reference in New Issue
Block a user