Functional Fixes — Cycle 2

Date: 2026-04-08 Working directory: C:\Users\keen4\WxManBran\tools\tropical-update-publisher\build_v2\v1\tools\tropical-update-publisher

F053 — Config Load, Save, Atomic Write, And Migration

  • Spec reference: Section 30.2, Section 30.1
  • Root cause: This remained PARTIAL because the cycle report treated migration verification as stale, even though the codebase already had a real on-disk migration-chain test and a persisted e2e artifact.
  • Files changed: none
  • What done: Re-verified the existing migration-chain implementation instead of changing stable code. Confirmed ConfigService still runs ordered migrations, writes config.json.v{n}.bak, persists the upgraded file, and preserves the expected migrated fields.
  • Verification:
    • npm test -- tests/main/configService.test.ts
    • npm test
    • Existing artifact confirmed: refinement-state/test-fixtures/cycle-2/config-migration-e2e-result.json
  • Risk: Low. No code path changed; this is a verification closure on already-implemented migration behavior.

F069 — paths:resolve Utility IPC

  • Spec reference: Undocumented utility gap tracked by master list F069; justified by Section 7.1/7.2 path exposure expectations and Section 8 incoming-post path rules
  • Root cause: window.api.pathsResolve was exposed in preload and typed in shared contracts, but src/main/ipc/router.ts still left paths:resolve on the generic NOT_IMPLEMENTED stub path.
  • Files changed:
    • src/main/ipc/handlers/utilityHandlers.ts
    • src/main/ipc/router.ts
    • src/shared/types/ipc.ts
    • tests/main/utilityHandlers.test.ts
    • tests/main/ipcRouter.test.ts
  • What done: Implemented a real paths:resolve handler that validates the incoming filename, loads config safely, normalizes incomingPostsPath, and returns both the absolute filesystem target and git-relative POSIX path.
  • Verification:
    • npm test -- tests/main/utilityHandlers.test.ts tests/main/ipcRouter.test.ts
    • npm run typecheck
    • npm test
  • Risk: Low. The handler is pure/read-only and now shares the same path normalization rules already used by publish/file-copy code.

F070 — Onboarding Completion IPC

  • Spec reference: Section 23.10
  • Root cause: window.api.onboardingComplete existed in preload/shared typing, but the main router never registered a handler, so onboarding completion state could not be persisted.
  • Files changed:
    • src/main/ipc/handlers/utilityHandlers.ts
    • src/main/ipc/router.ts
    • src/shared/types/ipc.ts
    • tests/main/utilityHandlers.test.ts
    • tests/main/ipcRouter.test.ts
  • What done: Added a real onboarding:complete handler that validates the answers payload, flips config.onboardingComplete to true, skips redundant rewrites when already complete, and appends an audit line when audit deps are present.
  • Verification:
    • npm test -- tests/main/utilityHandlers.test.ts tests/main/ipcRouter.test.ts
    • npm run typecheck
    • npm test
  • Risk: Low. The handler mutates only one persisted flag and reuses the existing config save path.

F083 — First-Run Accessibility Baseline

  • Spec reference: Section 23.10, Section 23.11
  • Root cause: Live Electron rejected first-run path validation through an invoke-serialization path that degraded the structured error into generic or raw wrapper text, so the renderer did not reliably announce the specific invalid-path message outside the test double.
  • Files changed:
    • src/main/services/firstRun/FirstRunGate.ts
    • src/preload/index.ts
    • src/renderer/features/first-run/FirstRunModal.tsx
    • src/shared/types/ipc.ts
    • tests/main/firstRunGate.test.ts
    • tests/renderer/firstRunModal.test.tsx
    • tests/preload/apiShape.test.ts
  • What done:
    • Changed firstRun:submitPath to return a typed { success: false, code, message } payload for validation/save failures instead of depending on rejected-object serialization.
    • Updated the renderer modal to consume failure payloads directly and to keep permissive fallback parsing for wrapped Electron errors.
    • Kept the live inline alert semantics (role="alert", aria-invalid, aria-errormessage) intact.
  • Verification:
    • npm test -- tests/main/firstRunGate.test.ts tests/renderer/firstRunModal.test.tsx
    • npm test -- tests/preload/apiShape.test.ts tests/renderer/firstRunModal.test.tsx
    • npm run build
    • npm test
    • Live screenshot verified with exact inline copy: refinement-state/screenshots/cycle-2/interactive-first-run-invalid-path-fixed8-153259.png
  • Risk: Low to medium. This is a contract change for firstRun:submitPath, but the only renderer consumer was updated in the same pass and the full suite stayed green.

Final Verification

  • npm run build: PASS
  • npm run typecheck: PASS
  • npm test: PASS (554 tests)
  • Live first-run invalid-path UI verified visually with restored exact inline error copy.

IMPLEMENTATION_COMPLETE