---
id: TASK-1.4
title: 'Phase 4: Fix runtime bugs and naming/code-quality issues'
status: Done
assignee:
  - codex
created_date: '2026-02-10 18:46'
updated_date: '2026-02-11 03:35'
labels: []
dependencies:
  - TASK-1.3
references:
  - plan.md
  - src/main.ts
  - src/core/services/overlay-visibility-service.ts
  - src/core/services/tokenizer-deps-runtime-service.ts
parent_task_id: TASK-1
ordinal: 2000
---

## Description

<!-- SECTION:DESCRIPTION:BEGIN -->
Address identified correctness and code-quality issues from plan.md, including race conditions, unsafe typing, callback rejection handling, and runtime naming cleanup.
<!-- SECTION:DESCRIPTION:END -->

## Acceptance Criteria
<!-- AC:BEGIN -->
- [x] #1 Debug `console.log`/`console.warn` usage in overlay visibility logic is removed or replaced with structured logging where needed.
- [x] #2 Tokenizer type mismatch is fixed without unsafe `as never` casting.
- [x] #3 Field grouping resolver handling is made concurrency-safe against overlapping requests.
- [x] #4 Async callback wiring in CLI/IPC paths has explicit rejection handling.
- [x] #5 Remaining `-runtime-service` naming cleanup is completed without logic regressions.
- [x] #6 `pnpm run build && pnpm run test:core` passes and manual startup/overlay smoke checks succeed.
<!-- AC:END -->

## Implementation Plan

<!-- SECTION:PLAN:BEGIN -->
1. Remove or replace debug `console.log`/`console.warn` usage in `overlay-visibility-service.ts` while preserving useful operational logging semantics.
2. Confirm and fix unsafe tokenizer casting paths (already partially addressed during Phase 2) and ensure no remaining `as never` escape hatches in tokenizer dependency flows.
3. Make field grouping resolver handling in `main.ts` concurrency-safe by adding request sequencing and stale-resolution guards.
4. Audit async callback wiring in CLI/IPC integrations and add explicit rejection handling where promises are fire-and-forget.
5. Execute `pnpm run build && pnpm run test:core` and document manual smoke-test steps/outcomes.
<!-- SECTION:PLAN:END -->

## Implementation Notes

<!-- SECTION:NOTES:BEGIN -->
Removed debug overlay-visibility `console.log`/`console.warn` statements from `overlay-visibility-service.ts`.

Eliminated unsafe tokenizer cast path during prior consolidation (`createTokenizerDepsRuntimeService` now uses typed `Token[]` and `mergeTokens(rawTokens)` without `as never`).

Added field-grouping overlap protection: `createFieldGroupingCallbackService` now cancels immediately when another resolver is active and only clears resolver state if the current resolver matches, preventing stale timeout/request cleanup from clobbering a newer resolver.

Added explicit rejection handling for async callback pathways: `shell.openExternal` now has `.catch(...)`; app lifecycle `whenReady` path now catches handler rejection; second-instance CLI dispatch is wrapped in try/catch logging.

Verification: `pnpm run build && pnpm run test:core` passes after these fixes.

Remaining in TASK-1.4: criterion #5 (`-runtime-service` naming cleanup batch) and criterion #6 manual smoke checks.

Completed `-runtime-service` naming cleanup for remaining modules by renaming files/tests and import paths, including: `overlay-bridge`, `field-grouping-overlay`, `mpv-control`, `runtime-options-ipc`, `mining`, `jimaku`, `anki-jimaku`, startup/app-ready test names, and subsync wrapper (`subsync-runner-service.ts`).

Resolved rename collision with existing `subsync-service.ts` by restoring original core subsync service from `HEAD` and moving runtime wrapper logic into `subsync-runner-service.ts`.

Verification after rename cleanup: `pnpm run build && pnpm run test:core` passes with updated test paths in `package.json`.

Manual smoke checks are still pending for criterion #6.

Smoke run attempt 1 (outside sandbox): `timeout 20s pnpm run start` started successfully, loaded config, initialized websocket/Mecab, and entered normal MPV reconnect loop when `/tmp/subminer-socket` was absent; no immediate startup crash after previous refactors.

Smoke run attempt 2 (outside sandbox): `timeout 20s pnpm exec electron . --start --auto-start-overlay` showed the same stable startup/reconnect behavior, but overlay activation could not be verified in this headless/non-interactive environment.

Manual GUI interactions (overlay render/toggle, mine card flow, field-grouping interaction) remain pending for a real desktop session with MPV running.

Automated interactive-smoke surrogate 1 (outside sandbox): started app, sent `--toggle`, then `--stop`; instance remained stable and cleanly stopped without crash.

Automated interactive-smoke surrogate 2 (outside sandbox): started app, sent `--trigger-field-grouping`, then `--stop`; command path executed without runtime crash and app shut down cleanly.

Observed expected reconnect behavior when MPV socket was absent (`ENOENT /tmp/subminer-socket`), with no regressions in startup/bootstrap flow.

Note: this environment is headless, so visual overlay rendering cannot be directly confirmed; command-path and process-lifecycle smoke checks passed.
<!-- SECTION:NOTES:END -->

## Final Summary

<!-- SECTION:FINAL_SUMMARY:BEGIN -->
Completed Phase 4 by removing debug logging noise, fixing unsafe typing and concurrency risks, adding async rejection handling, completing naming cleanup, and validating startup/command-path behavior through repeated build/test and live Electron smoke runs.
<!-- SECTION:FINAL_SUMMARY:END -->
