# Phase 2: Kintsugi REST + CH Connection Fix (P1-P2) - Context

**Gathered:** 2026-03-20
**Status:** Ready for planning

<domain>
## Phase Boundary

Thread-local ClickHouse cache for kintsugi workers + REST concurrency limiting to prevent fd exhaustion and hour-long repairs.

</domain>

<decisions>
## Implementation Decisions

### Claude's Discretion

All implementation choices are at Claude's discretion — pure infrastructure phase.

</decisions>

<code_context>

## Existing Code Insights

### Reusable Assets

- `scripts/repair_direct_parquet.py:76-82` — existing `threading.local()` + `_get_worker_cache()` pattern (exact template for kintsugi)
- `python/opendeviationbar/kintsugi.py:1079` — `_try_parquet_day_replace()` (needs thread-local cache)
- `python/opendeviationbar/kintsugi.py:1183` — `_try_vision_day_replace()` (needs thread-local cache)
- `python/opendeviationbar/kintsugi.py:648` — `_shard_is_parquet_cached()` (extend for Vision availability)
- `python/opendeviationbar/kintsugi.py:1694` — parquet-cached check in `kintsugi_pass()`

### Established Patterns

- `MAX_CONCURRENT_REPAIRS=24` governs thread pool size for kintsugi
- `OpenDeviationBarCache()` creates CH connection per instantiation (root cause of fd churn)
- `_shard_is_parquet_cached()` checks local Parquet only — no Vision check yet

### Integration Points

- `kintsugi_pass()` orchestrates candidate selection and worker dispatch
- `_repair()` is the per-shard worker function called by ThreadPoolExecutor
- Environment variables follow `OPENDEVIATIONBAR_KINTSUGI_*` namespace

</code_context>

<specifics>
## Specific Ideas

No specific requirements — infrastructure phase.

</specifics>

<deferred>
## Deferred Ideas

None — discussion stayed within phase scope.

</deferred>
