--- phase: 02-config-overlays plan: 02 type: execute wave: 2 depends_on: ["02-01"] files_modified: - src/cli/doctor.ts autonomous: true must_haves: truths: - "Running flynn doctor with FLYNN_ENV=staging (no staging.yaml) reports a clear error identifying the missing overlay file" - "Running flynn doctor without FLYNN_ENV shows no overlay-related check (or passes silently)" - "Running flynn doctor with FLYNN_ENV=docker and docker.yaml present shows overlay check passing" artifacts: - path: "src/cli/doctor.ts" provides: "checkOverlayExists check for FLYNN_ENV overlay validation" contains: "checkOverlay" key_links: - from: "src/cli/doctor.ts" to: "src/cli/shared.ts" via: "imports resolveOverlayPath to determine overlay path" pattern: "resolveOverlayPath" --- Add overlay file validation to `flynn doctor` — when FLYNN_ENV is set, verify the corresponding overlay YAML file exists. Purpose: Give operators clear diagnostic feedback when their environment overlay is misconfigured, rather than a cryptic file-not-found error at startup. Output: New doctor check in the existing checks array. @/home/will/.config/opencode/get-shit-done/workflows/execute-plan.md @/home/will/.config/opencode/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/02-config-overlays/02-01-SUMMARY.md @src/cli/doctor.ts @src/cli/shared.ts Task 1: Add checkOverlayExists to doctor.ts src/cli/doctor.ts Import `resolveOverlayPath` from `./shared.js` (add to existing import line). Create a new check function following the existing pattern: ```typescript const checkOverlayExists: Check = async (ctx) => { const overlayPath = resolveOverlayPath(ctx.configPath); if (!overlayPath) { return { status: 'skip', label: 'Config overlay', detail: '(FLYNN_ENV not set)' }; } const env = process.env.FLYNN_ENV; if (existsSync(overlayPath)) { return { status: 'pass', label: 'Config overlay', detail: `(${env}.yaml found)` }; } return { status: 'fail', label: 'Config overlay', detail: `FLYNN_ENV=${env} but ${overlayPath} not found` }; }; ``` Insert `checkOverlayExists` into the `allChecks` array — place it right after `checkConfigExists` and before `checkConfigParses`. This is the natural position: first check the base config exists, then check the overlay exists, then parse/validate the merged result. The updated array should be: ```typescript const allChecks: Check[] = [ checkConfigExists, checkOverlayExists, // <-- NEW checkConfigParses, checkConfigValidates, checkEnvVars, checkDataDir, checkSessionDb, checkModelConnectivity, checkTelegram, checkMcpServers, checkSkills, checkTailscale, ]; ``` Note: `existsSync` is already imported at the top of doctor.ts. `resolveOverlayPath` needs to be added to the import from `./shared.js`. Run `pnpm test:run` to verify no regressions. Run `pnpm typecheck` for type safety. Run `pnpm typecheck` — no type errors. Run `pnpm test:run` — full suite passes (1077+ tests). checkOverlayExists added to doctor.ts checks array. When FLYNN_ENV is set, doctor reports pass/fail for overlay file existence with the overlay path in the detail. When FLYNN_ENV is not set, the check is skipped. Full test suite passes. 1. `pnpm typecheck` — no type errors 2. `pnpm test:run` — full suite passes (1077+ tests) 3. Manual: `FLYNN_ENV=nonexistent pnpm start -- doctor` should show FAIL for Config overlay 4. Manual: `pnpm start -- doctor` (no FLYNN_ENV) should show SKIP for Config overlay - checkOverlayExists is in the doctor checks array after checkConfigExists - FLYNN_ENV=staging with no staging.yaml → doctor reports FAIL with "FLYNN_ENV=staging but /path/to/staging.yaml not found" - No FLYNN_ENV → doctor skips the overlay check - FLYNN_ENV=docker with docker.yaml present → doctor reports PASS - Full test suite passes with zero regressions After completion, create `.planning/phases/02-config-overlays/02-02-SUMMARY.md`