feat(ingest): record suppressed OCR escalations (what-if-OCR signal)
OCR is the paid, opt-in tier (DOCUMENT_OCR_ENABLED, default off). The per-tier
escalation gate already declines to hop to OCR when it's disabled (the pre-OCR
tier is terminal — no surprise cost), but that left operators blind to how much
OCR demand exists.
evaluate_escalation now returns a structured EscalationDecision:
- "hop" — a higher tier can run; the caller raises EscalateError (queue-hop).
- "suppressed" — the ideal next tier (e.g. ocr) exists but is DISABLED; the caller
indexes the current tier's output as terminal and records the
would-be hop on the new astrolabe_document_escalation_suppressed_total
{from_tier,to_tier,reason} counter instead of hopping.
- None — index as-is (good text, or no such tier at all).
So with OCR off, escalation_suppressed_total{to_tier="ocr"} is the latent OCR
demand an operator weighs before enabling OCR; enabling it converts these into
real document_escalation_total{to_tier="ocr"} hops. next_available_tier gains an
ignore_enabled flag to compute the *ideal* (enabled-gate-ignored) target.
Tests: registry suppressed vs hop vs terminal (incl. structured-hop-not-suppressed
when OCR off but structured available); _parse_pdf_tier records suppressed +
indexes without raising.
Deck #324 (parent #323).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
6db48830af
commit
a27ddb2d5a
@@ -276,6 +276,21 @@ document_escalation_total = Counter(
|
||||
["from_tier", "to_tier", "reason"],
|
||||
)
|
||||
|
||||
# Would-be escalations SUPPRESSED because the target tier is disabled (Deck
|
||||
# #324). The cost-sensitive ``ocr`` tier is opt-in (DOCUMENT_OCR_ENABLED): when
|
||||
# it's off, a doc the classifier would route to OCR is indexed at the pre-OCR
|
||||
# tier instead of hopping, and that intent is counted here rather than on
|
||||
# document_escalation_total. This is the "what-if OCR were enabled" signal —
|
||||
# escalation_suppressed_total{to_tier="ocr"} is the latent OCR demand an operator
|
||||
# weighs before enabling OCR; enabling it converts these into real
|
||||
# document_escalation_total{to_tier="ocr"} hops.
|
||||
document_escalation_suppressed_total = Counter(
|
||||
"astrolabe_document_escalation_suppressed_total",
|
||||
"Would-be tier escalations suppressed because the target tier is disabled",
|
||||
# reason: low_confidence | empty_text
|
||||
["from_tier", "to_tier", "reason"],
|
||||
)
|
||||
|
||||
# Hard parse failures: the parse now runs in an isolated subprocess, so a
|
||||
# timeout/OOM that kills the worker is caught here. This is distinct from
|
||||
# ``document_parse_total{status="error"}`` (an in-process exception): a hard
|
||||
@@ -746,6 +761,20 @@ def record_document_escalation(from_tier: str, to_tier: str, reason: str) -> Non
|
||||
).inc()
|
||||
|
||||
|
||||
def record_document_escalation_suppressed(
|
||||
from_tier: str, to_tier: str, reason: str
|
||||
) -> None:
|
||||
"""Record a would-be escalation suppressed because ``to_tier`` is disabled.
|
||||
|
||||
The "what-if OCR were enabled" signal (Deck #324): the document is indexed at
|
||||
``from_tier`` (terminal) rather than hopped, because the ideal next tier
|
||||
(typically ``ocr``) is turned off. See ``document_escalation_suppressed_total``.
|
||||
"""
|
||||
document_escalation_suppressed_total.labels(
|
||||
from_tier=from_tier, to_tier=to_tier, reason=reason
|
||||
).inc()
|
||||
|
||||
|
||||
def record_document_parse_failed(reason: str) -> None:
|
||||
"""Record a hard parse failure from the isolated worker.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user