rag-service/openspec/specs/ocr-processing/spec.md

4.1 KiB
Raw Permalink Blame History

OCR Processing Specification

Purpose

Define safe OCR behavior.

Requirements

Requirement: Per-Page Native Detection

The system MUST evaluate PDF pages independently. Native text is sufficient only when N >= 120, A >= 80, W >= 20, and R <= 0.01, under pdf-detection-v1.

Scenario: Textual pages bypass OCR

  • GIVEN every page meets native thresholds
  • WHEN extraction completes
  • THEN native text MUST be selected and no OCR job MAY be created

Scenario: Mixed PDF selects exact pages

  • GIVEN only some pages fail any native threshold
  • WHEN detection completes
  • THEN OCR MUST receive those unique, ordered, one-based pages
  • AND N == 0 MUST always request OCR inspection

Requirement: Blank and OCR Quality Gates

A page MAY be blank only with inkCoverage < 0.015 and fewer than 10 OCR characters. Non-blank OCR MUST meet nonWhitespaceCharacters >= 40, median >= 0.80, p10 >= 0.50, and low-confidence ratio <= 0.20.

Scenario: Verified blank contributes no text

  • GIVEN both blank conditions hold
  • WHEN the page is classified
  • THEN it MUST be blank and contribute no candidate text

Scenario: Visible ink fails closed

  • GIVEN visible ink and OCR fails the quality gate
  • WHEN processing completes
  • THEN the page MUST NOT be blank and the version MUST fail with OCR_QUALITY_BLOCKED

Requirement: Deterministic Candidate Composition

The system MUST use native text or OCR lines, never both per page. It SHALL order lines by top, left, and original index; pages ascending; and separate non-blank pages with --- Page N ---.

Scenario: Candidate is reproducible

  • GIVEN identical validated page records
  • WHEN the candidate is composed repeatedly
  • THEN canonical text, ordering, and hashes MUST be identical
  • AND raw OCR and native extraction MUST remain available for audit

Requirement: Risk Tokens Remain Uncorrected

The system MUST mark \b[A-Za-z]{2,}[A-Za-z0-9_-]*\d[A-Za-z0-9_-]*\b tokens and elevate ambiguous, differing, unique, or context-adjacent ones. It MUST NOT auto-correct casing or O/0, I/1/l, or S/5.

Scenario: Known code ambiguities are flagged

  • GIVEN OCR emits CBGO4a, FATo7, DSAuo8, or NSAvo6
  • WHEN risk analysis runs
  • THEN each token MUST be shown for human review unchanged

Requirement: Private Idempotent OCR Service

Private PaddleOCR 3.4.0 with PaddlePaddle CPU 3.2.2 MUST require bearer authorization, allowlisted jobs, and deterministic identity for identical hash, config, and pages. It MUST NOT be Internet-accessible.

Scenario: Idempotent submission

  • GIVEN valid requests share a key and payload
  • WHEN both are submitted
  • THEN both MUST identify one job and result without duplicate processing

Scenario: Conflicting or invalid submission

  • GIVEN a reused key conflicts, authentication fails, or configuration is disallowed
  • WHEN submission occurs
  • THEN OCR MUST return the contracted 409, 401/403, or 400 class

Scenario: Result integrity mismatch

  • GIVEN returned integrity fields differ from the request
  • WHEN RAG validates the result
  • THEN processing MUST fail without a reviewable candidate

Requirement: Operational Limits and Health

OCR MUST enforce 50 MiB, 100 pages, 200 DPI, 25 megapixels/page, one concurrent job, one replica, queue depth three, 60 seconds/page, 15 minutes total, and 3 CPU/5 GiB maximum. Readiness MUST await pinned models; polling SHALL back off 2–15 seconds.

Scenario: Unsafe input is rejected before render

  • GIVEN a PDF is oversized, encrypted, corrupt, too long, or decompression-unsafe
  • WHEN it is accepted for processing
  • THEN it MUST be rejected before full render without changing the active version

Scenario: Queue or transient service pressure

  • GIVEN the queue is full or OCR is transiently unavailable
  • WHEN RAG submits work
  • THEN 429 MUST remain retryable; connection/502/503 failures MUST allow at most two same-key resubmissions

Scenario: Deterministic failure is not retried

  • GIVEN OCR returns 400, 401, 403, 413, 422, or deterministic render failure
  • WHEN RAG handles the response
  • THEN it MUST NOT retry or switch engines