From f8e8645fc2347d74a4f9b5c27299860264e0be1e Mon Sep 17 00:00:00 2001 From: Chris Coutinho Date: Sat, 13 Jun 2026 15:20:16 +0200 Subject: [PATCH] fix(ingest): address review round 1 (Literal kind + log tidy) - escalation: EscalationDecision.kind is now Literal["hop","suppressed"] so ty catches a bad kind statically (and the processor branch is exhaustive). - processor: simplify the suppressed-escalation log line (no longer repeats to_tier / tier). - registry: clarify _tier_available's ignore_enabled drops the OCR-enabled gate specifically (a future per-tier gate would extend the condition). Deck #324. Co-Authored-By: Claude Opus 4.8 (1M context) --- nextcloud_mcp_server/document_processors/escalation.py | 3 ++- nextcloud_mcp_server/document_processors/registry.py | 9 +++++---- nextcloud_mcp_server/vector/processor.py | 6 ++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nextcloud_mcp_server/document_processors/escalation.py b/nextcloud_mcp_server/document_processors/escalation.py index d85733f6..3eba0986 100644 --- a/nextcloud_mcp_server/document_processors/escalation.py +++ b/nextcloud_mcp_server/document_processors/escalation.py @@ -22,6 +22,7 @@ mapping lives in the queue layer, which imports :class:`EscalateError` from here from __future__ import annotations from dataclasses import dataclass +from typing import Literal # Cheapest-first. ``llm`` is reserved (see base.DocumentProcessor.tier) and not # wired yet, so it is intentionally absent from the live ladder. @@ -46,7 +47,7 @@ class EscalationDecision: exists at all (no processor registered for it). """ - kind: str # "hop" | "suppressed" + kind: Literal["hop", "suppressed"] to_tier: str reason: str # empty_text | low_confidence diff --git a/nextcloud_mcp_server/document_processors/registry.py b/nextcloud_mcp_server/document_processors/registry.py index 87f9dce4..188b567a 100644 --- a/nextcloud_mcp_server/document_processors/registry.py +++ b/nextcloud_mcp_server/document_processors/registry.py @@ -400,10 +400,11 @@ class ProcessorRegistry: (so OCR stays opt-in and a misconfigured tenant never escalates to a backend it hasn't turned on). - ``ignore_enabled`` drops only the *enabled* gate (not the registered- - processor requirement): it answers "would this tier run if it were turned - on?" — used to compute the *ideal* escalation target for the - what-if-OCR suppressed-escalation signal. + ``ignore_enabled`` drops only the OCR-enabled gate (not the registered- + processor requirement): it answers "would this tier run if OCR were turned + on?" — used to compute the *ideal* escalation target for the what-if-OCR + suppressed-escalation signal. (Today only ``ocr`` has an enabled gate; a + future per-tier gate would extend the condition below.) """ if self._pdf_processor_for_tier(tier) is None: return False diff --git a/nextcloud_mcp_server/vector/processor.py b/nextcloud_mcp_server/vector/processor.py index 0423550e..be570ad8 100644 --- a/nextcloud_mcp_server/vector/processor.py +++ b/nextcloud_mcp_server/vector/processor.py @@ -165,14 +165,12 @@ async def _parse_pdf_tier( tier, decision.to_tier, decision.reason ) logger.info( - "Escalation suppressed for %s %s->%s (reason=%s; %s disabled), " - "indexing at %s", + "Escalation suppressed for %s: %s->%s disabled (reason=%s), " + "indexing at current tier", filename or "", tier, decision.to_tier, decision.reason, - decision.to_tier, - tier, ) elif decision is not None: record_document_escalation(tier, decision.to_tier, decision.reason)