From 5b3e6374232f6105b904ac7704c10834b43bf6f5 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Sun, 4 Oct 2026 02:48:48 -0700 Subject: [PATCH] [grade=B urn:ump:mao7vadnesmquhmgr4oeg554edt6fn3ykxyiydtfs2psoekd4s7q] P7 tailscale provider: wire coord client via ctx delegation Dogfood finding #2: createTailscaleProvider() built with coordClient=null; nothing in prod ever called attachCoordClient() (the wiring the provider docblock promised never landed), so wizard credential validation always failed not_configured even with a valid stored token. Pass a delegating proxy that fetches a fresh coord client per call via the sanctioned ctx.tailscaleCoord.getClient pattern (token re-read from credentialManager each call). Full suite 3413/3413. --- dashcaddy-api/src/app.js | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/dashcaddy-api/src/app.js b/dashcaddy-api/src/app.js index f5ca7ca..2d1d3e6 100644 --- a/dashcaddy-api/src/app.js +++ b/dashcaddy-api/src/app.js @@ -779,7 +779,29 @@ async function createApp() { // Private Network wizard (DC-152). Dogfood finding 2026-10-04: the wizard // factory needs INSTANCES keyed by mode id; without them every mode // selection 503s provider_unavailable (unit tests inject their own map). - const p7TailscaleProvider = require('./network/providers/tailscale').createTailscaleProvider(); // eslint-disable-line global-require + // Coord client wiring (dogfood finding #2, 2026-10-04): the provider is + // built with coordClient=null and nothing ever called attachCoordClient() + // in prod (the promised routes/network.js wiring never landed), so wizard + // credential validation always failed not_configured. Delegate every coord + // method to a FRESH client per call — the sanctioned context pattern + // (ctx.tailscaleCoord.getClient re-reads the token from credentialManager + // each call, so wizard-stored tokens take effect without a restart). + const p7CoordProxy = new Proxy({}, { + get(_t, prop) { + if (typeof prop !== 'string') return undefined; + return async (...args) => { + const client = await ctx.tailscaleCoord.getClient(); + const fn = client ? client[prop] : null; + if (typeof fn !== 'function') { + throw new Error('coord client method unavailable: ' + String(prop)); + } + return fn.apply(client, args); + }; + }, + }); + const p7TailscaleProvider = require('./network/providers/tailscale').createTailscaleProvider({ // eslint-disable-line global-require + coordClient: p7CoordProxy, + }); const p7WireGuardProvider = require('./network/providers/wireguard').createWireGuardProvider(); // eslint-disable-line global-require apiRouter.use('/network/wizard', networkWizardRoutes({ registry: { getActiveProvider },