Summary
Watch cancellation only stops the polling loop, while active indexing cannot receive the token; watch also captures output by replacing Console.Out process-wide.
v1.38.0 evidence / reproduction / control flow
IndexWatchRunner.cs:175-200 observes cancellation between runs, but synchronous RunPartialUpdate/RunFullRescan calls eventually invoke IndexCommandRunner.Run(args) without a cancellation token (IndexWatchRunner.cs:424-468). The same block calls Console.SetOut(captureWriter), so unrelated threads can be captured or lose their output.
Impact
Ctrl+C can hang behind a blocked extractor or I/O operation, and embedded/multi-runner hosts can produce corrupted or misrouted JSONL.
Suggested direction / acceptance criteria
- Thread a linked cancellation token through every watch sub-run and long-running indexing phase.
- Inject an output abstraction into the runner instead of mutating
Console.Out.
- Add tests for cancellation during an active sub-run and concurrent output from another runner/thread.
Dogfooding candidate IDs: M045, M046.
Observed with locally built cdidx v1.38.0 from origin/main on 2026-07-15.
Summary
Watch cancellation only stops the polling loop, while active indexing cannot receive the token; watch also captures output by replacing
Console.Outprocess-wide.v1.38.0 evidence / reproduction / control flow
IndexWatchRunner.cs:175-200observes cancellation between runs, but synchronousRunPartialUpdate/RunFullRescancalls eventually invokeIndexCommandRunner.Run(args)without a cancellation token (IndexWatchRunner.cs:424-468). The same block callsConsole.SetOut(captureWriter), so unrelated threads can be captured or lose their output.Impact
Ctrl+C can hang behind a blocked extractor or I/O operation, and embedded/multi-runner hosts can produce corrupted or misrouted JSONL.
Suggested direction / acceptance criteria
Console.Out.Dogfooding candidate IDs: M045, M046.
Observed with locally built cdidx v1.38.0 from origin/main on 2026-07-15.