diff --git a/crates/kebab-config/src/lib.rs b/crates/kebab-config/src/lib.rs index d02cdcd..a1499c4 100644 --- a/crates/kebab-config/src/lib.rs +++ b/crates/kebab-config/src/lib.rs @@ -484,14 +484,19 @@ impl PdfOcrCfg { } /// PDF OCR per-page request timeout 의 기본값. -/// 6-32s 가 정상 throughput; 60s 초과는 Ollama 다운 / 매우 dense·고해상도 page 의 신호. +/// 6-32s 가 정상 throughput; 180s 초과는 Ollama 다운 / 매우 dense·고해상도 page 의 신호. /// `config.toml` 의 `[pdf.ocr] request_timeout_secs = N` 로 override. /// /// HOTFIXES 2026-05-27 (Bug #11): metro-korea.pdf dogfood 에서 page 8/13 모두 /// 기존 600s default 까지 완전 timeout (`chars: 0, skipped: true` × 20분 cost) → -/// 60s 로 하향. parent spec §1000 / §1628 OQ-1 ("CPU 환경 105s 의 5x 여유") 가 +/// 우선 60s 로 하향. parent spec §1000 / §1628 OQ-1 ("CPU 환경 105s 의 5x 여유") 가 /// 가정한 "page 당 평균 105s" 보다 실측 cloud GPU Ollama 가 6-32s 로 훨씬 빠름. -fn default_pdf_ocr_request_timeout_secs() -> u64 { 60 } +/// +/// HOTFIXES 2026-05-28 (Bug #11 follow-up): 60s 는 dense Korean page (특히 +/// metro-korea.pdf page 8/9/13) 의 OCR 을 강제 timeout 시켜 본문 indexed 손실. +/// **conservative starting point 180s 로 재조정** + dogfood evidence 기반 sweet spot +/// 점진적 축소 정책. user 가 `[pdf.ocr] request_timeout_secs = N` 으로 직접 tune. +fn default_pdf_ocr_request_timeout_secs() -> u64 { 180 } fn default_pdf_ocr_valid_ratio() -> f32 { 0.5 } fn default_pdf_ocr_min_char_count() -> u32 { 20 } fn default_pdf_ocr_lang_hint() -> Option { Some("kor".to_string()) } @@ -1853,12 +1858,13 @@ mod fb27_tests { } #[test] - fn pdf_ocr_request_timeout_default_is_60s() { - // Bug #11 (dogfood 2026-05-27): default 600s → 60s. + fn pdf_ocr_request_timeout_default_is_180s() { + // Bug #11 (dogfood 2026-05-27 + follow-up 2026-05-28): + // default 600s → 60s → 180s (sweet spot 점진적 축소 정책). let cfg = PdfOcrCfg::defaults(); assert_eq!( - cfg.request_timeout_secs, 60, - "pdf.ocr.request_timeout_secs default must be 60s (Bug #11, HOTFIXES 2026-05-27)" + cfg.request_timeout_secs, 180, + "pdf.ocr.request_timeout_secs default must be 180s (Bug #11, HOTFIXES 2026-05-28)" ); } } diff --git a/crates/kebab-config/tests/pdf_ocr.rs b/crates/kebab-config/tests/pdf_ocr.rs index 92c9028..77ea14b 100644 --- a/crates/kebab-config/tests/pdf_ocr.rs +++ b/crates/kebab-config/tests/pdf_ocr.rs @@ -52,7 +52,7 @@ fn pdf_ocr_defaults_off_with_qwen_3b() { assert!(cfg.pdf.ocr.endpoint.is_none()); assert_eq!(cfg.pdf.ocr.languages, vec!["eng".to_string(), "kor".to_string()]); assert_eq!(cfg.pdf.ocr.max_pixels, 2048); - assert_eq!(cfg.pdf.ocr.request_timeout_secs, 60); // Bug #11: default 600 → 60 + assert_eq!(cfg.pdf.ocr.request_timeout_secs, 180); // Bug #11: 600 → 60 → 180 (HOTFIXES 2026-05-28) assert!((cfg.pdf.ocr.valid_ratio_threshold - 0.5).abs() < 1e-6); assert_eq!(cfg.pdf.ocr.min_char_count, 20); assert_eq!(cfg.pdf.ocr.lang_hint.as_deref(), Some("kor")); diff --git a/tasks/HOTFIXES.md b/tasks/HOTFIXES.md index 75103c6..0c57ee7 100644 --- a/tasks/HOTFIXES.md +++ b/tasks/HOTFIXES.md @@ -14,7 +14,24 @@ historical contract that was implemented; this file accumulates the deltas so phase 5+ readers can find the live behavior without diffing git history. -## 2026-05-27 — PDF OCR `request_timeout_secs` default 600s → 60s (Bug #11) +## 2026-05-28 — PDF OCR `request_timeout_secs` default 60s → 180s (Bug #11 follow-up) + +**Discovered**: v0.20.0 final dogfood (2026-05-28), round 3 fresh KB ingest. + +**Symptom**: 60s default 가 metro-korea.pdf 의 page 8/9/13 (dense Korean text + Identity-H CID font) 의 OCR 을 강제 timeout. round 2 (600s default) 의 page 8/13 (2 page) → round 3 (60s) 의 page 8/9/13 (3 page) — **1 page 더 timeout** + 본문 indexed 손실 증가. 사용자 perspective: cost 절약 vs coverage trade-off 가 60s 에선 coverage 쪽으로 너무 깎임. + +**Decision**: **conservative starting point 180s 로 재조정** + dogfood evidence 기반 sweet spot 점진적 축소 정책. 180s 가 600s 의 1/3 cost cap (page 당 max 3분) 보장 + dense page coverage 회복. + +**Fix** (HOTFIXES 2026-05-28 follow-up, branch `feat/pdf-scanned-ocr`): +- `crates/kebab-config/src/lib.rs::default_pdf_ocr_request_timeout_secs() = 180`. +- Doc-comment 보강 — "180s starting point + sweet spot 점진적 축소" 명시. +- Unit test rename `pdf_ocr_request_timeout_default_is_60s` → `_is_180s` + assertion 180. +- `crates/kebab-config/tests/pdf_ocr.rs` 의 `assert_eq!(...request_timeout_secs, 60)` → `180`. +- User override path 보존 — `config.toml [pdf.ocr] request_timeout_secs = N` 로 늘리/줄이기 가능 (이미 `#[serde(default)]` field, 변경 0). + +**Future tuning policy**: 향후 dogfood 마다 OCR 평균 ms 분포 측정 후 (예: 90th percentile + buffer) default 점진적 축소. 60s 같은 짧은 default 로 직접 jump 안 함. + +## 2026-05-27 — PDF OCR `request_timeout_secs` default 600s → 60s (Bug #11, superseded by 2026-05-28 follow-up) **Discovered**: v0.20.0 final dogfood (2026-05-27), metro-korea.pdf 의 page 8 + 13. @@ -23,7 +40,7 @@ git history. **Root cause**: `default_pdf_ocr_request_timeout_secs() = 600` (spec `2026-05-27-pdf-scanned-ocr-spec.md` line 1000 + OQ-1 line 1628 의 "CPU 환경 105s 의 5x 여유" 가정). 실측 cloud GPU Ollama 의 per-page throughput 는 6-32s — 600s 까지 가야 timeout 이라면 Ollama 다운 상태가 사실상 확실. 600s 가 fail-fast 신호로 작동 안 함. **Fix** (v0.20.0 bugfix3 round 3, branch `feat/pdf-scanned-ocr`): -- `crates/kebab-config/src/lib.rs` `default_pdf_ocr_request_timeout_secs() = 60`. +- `crates/kebab-config/src/lib.rs` `default_pdf_ocr_request_timeout_secs() = 60` (2026-05-28 entry 에서 180 으로 재조정). - Doc-comment 보강 — 6-32s 정상 throughput, 60s 초과는 Ollama 다운 / 매우 dense·고해상도 page 신호. - User override path 보존 — `config.toml [pdf.ocr] request_timeout_secs = N` 로 늘릴 수 있음.