Corpus Quality Cycle
pageindex / ops

Corpus Quality Cycle

Automated loop: audit a corpus run, diagnose regressions, build fixes via RFC, re-ingest. Each iteration improves the 25-doc scorecard toward convergence.
Automated gate
Manual gate
Haiku Easy tasks
Sonnet Medium tasks
Opus Complex tasks
Fable Super complex tasks

Cycle Flow

flowchart TD
    classDef phase fill:#b5762a,color:#fff,stroke:none,font-weight:700
    classDef gate_auto fill:#2e7d6e,color:#fff,stroke:none,font-weight:700
    classDef gate_manual fill:#a8505a,color:#fff,stroke:none,font-weight:700
    classDef skill fill:#fff,color:#2a2520,stroke:#d8d4ce,stroke-width:1px
    classDef output fill:#fdf6ed,color:#2a2520,stroke:#d4943a,stroke-width:1px
    classDef decision fill:#fdf0f1,color:#2a2520,stroke:#a8505a,stroke-width:1px
    classDef checkpoint fill:#edf7f5,color:#2a2520,stroke:#2e7d6e,stroke-width:1px

    START(["corpus:cycle orchestrator"]):::phase

    subgraph W1 ["Workflow 1 — Ingest"]
        WIPE["Wipe PG / MinIO / Redis"]:::skill
        RESTART["Restart workers + server"]:::skill
        INGEST["preprocess_client.py\n25-doc batch"]:::skill
    end
    START --> WIPE --> RESTART --> INGEST

    G0{"G0 — All 25 docs\nterminal state\n▸ Haiku · auto"}:::gate_auto
    INGEST --> G0

    subgraph W2 ["Workflow 2 — Score + Diff"]
        SCORE["corpus:score\nHybrid verdict\n▸ pipeline: Haiku fetch\n+ Sonnet judge"]:::skill
        DIFF["corpus:diff\nRun N vs N-1 delta\n▸ Haiku"]:::skill
        REPORT["Write audit report\n▸ Haiku"]:::skill
        AUDIT_FILE[/"audit/CORPUS_REINGESTION\n_AUDIT_RUN-N.md"/]:::output
    end
    G0 --> SCORE --> DIFF --> REPORT --> AUDIT_FILE

    G1{"G1 — Human reviews\nscorecard + convergence\n▸ manual"}:::gate_manual
    AUDIT_FILE --> G1

    CONVERGED{{"Converged?\n0 FAIL + 0 ERROR\n+ 0 regressions"}}:::decision
    G1 --> CONVERGED
    CONVERGED -- "Yes → stop" --> DONE(["Cycle complete"])

    subgraph W3 ["Workflow 3 — Diagnose + Plan"]
        TRIAGE["Triage\nCategorize by domain\n▸ Sonnet"]:::skill
        CLUSTER["Cluster Trace\nOne Opus agent per\ndomain cluster"]:::skill
        DRILLDOWN["Document Drill-down\nPer-doc investigation\n▸ Sonnet / Haiku"]:::skill
        CKPT_W3["Checkpoint\nPersist to disk\n▸ Haiku"]:::checkpoint
        RFC_DRAFT["corpus:plan\nOpus drafts RFC\nD-numbered decisions"]:::skill
        RFC_VERIFY{"Fable verifies\nmax 2 rounds"}:::skill
        RFC_REDRAFT["Opus re-drafts\nvia Serena MCP"]:::skill
        RFC_OK[/"RFC approved\n.agents/rfcs/NNN-slug.md"/]:::output
        ARTIFACT_BUILD["rfc-artifact-build\nGenerates design + tasks"]:::skill
        DESIGN_OUT[/".agents/designs/\ndesign-rfcNNN-slug.md"/]:::output
        TASKS_OUT[/".agents/tasks/\ntasks-rfcNNN-slug.md"/]:::output
    end
    CONVERGED -- "No → continue" --> TRIAGE
    TRIAGE --> CLUSTER
    CLUSTER -- "all explained" --> CKPT_W3
    CLUSTER -- "ambiguous docs" --> DRILLDOWN --> CKPT_W3
    CKPT_W3 --> RFC_DRAFT --> RFC_VERIFY
    RFC_VERIFY -- "rejected" --> RFC_REDRAFT --> RFC_VERIFY
    RFC_VERIFY -- "approved" --> RFC_OK
    RFC_OK --> ARTIFACT_BUILD
    ARTIFACT_BUILD --> DESIGN_OUT
    ARTIFACT_BUILD --> TASKS_OUT

    G2{"G2 — Human approves\nRFC + design + tasks\n▸ manual"}:::gate_manual
    DESIGN_OUT --> G2
    TASKS_OUT --> G2

    subgraph W4 ["Workflow 4 — Build"]
        direction TB
        WAVE["swarm-builder\nWave execution\n▸ pipeline: Sonnet build\n+ Fable/Opus review"]:::skill
        CHECK["Between-wave checkpoint\nL1: pytest · Haiku\nL2: review vs design · Fable/Opus\nL3: task acceptance · Fable/Opus\n+ Serena MCP task update"]:::skill
        MEND["corpus:mend\nTest repair if needed\n▸ Sonnet"]:::skill
    end
    G2 --> WAVE --> CHECK
    CHECK -- "pass + more waves" --> WAVE
    CHECK -- "tests broken" --> MEND --> WAVE
    CHECK -- "all waves done" --> G3

    G3{"G3 — Full suite green\nAll tasks marked done\n▸ Haiku · auto"}:::gate_auto

    subgraph W5 ["Workflow 5 — Sync + Commit"]
        SYNC["make confluence-local-sync\nNo LLM needed"]:::skill
        BATCH1["Batch 1: docs · .agents/\nRFC + design + tasks"]:::skill
        BATCH2["Batch 2: feat · src/\nImplementation"]:::skill
        BATCH3["Batch 3: test · tests/\nTest coverage"]:::skill
        BATCH4["Batch 4: docs · audit/\nScoring artifacts"]:::skill
        PUSH["git push\nall batches together\nno co-author trailers"]:::skill
    end
    G3 --> SYNC --> BATCH1 --> BATCH2 --> BATCH3 --> BATCH4 --> PUSH

    G4{"G4 — Clean tree\nCommit verified\n▸ Haiku · auto"}:::gate_auto
    PUSH --> G4

    G4 -- "Loop back\nwith fixes applied" --> WIPE
      
1
Ingest
Wipe derived state (PG/MinIO processed/Redis cache), restart MCP workers + server, run full corpus ingestion via preprocess_client.py.
corpus:cycle → shell
Environment Reset
Drop PG tables, clear MinIO processed/, flush Redis. Restart arq workers and MCP server. Confirm healthy via health endpoint.
corpus:cycle → shell
Batch Ingestion
Run preprocess_client.py against full 25-doc corpus. Monitor parallel workers via log tailing.
G0
All 25 docs reach terminal state (PASS/MARGINAL/FAIL/ERROR) auto Haiku
2
Score + Diff
Score every document with the hybrid verdict system via a two-stage pipeline (Haiku fetch + Sonnet judge), then diff against the previous run’s scorecard. Output: one audit file per run.
corpus:score → pipeline
Hybrid Verdict (2-stage pipeline)
Stage 1: Fetch — extract tree metrics (node count, depth, chars, garbled blocks, image markers, PictureResult enrichments). Haiku
Stage 2: Judge — subjective assessment (tree structure quality, content coverage, Arabic text order). Assigns verdict: PASS / MARGINAL / FAIL / ERROR. Sonnet
corpus:diff
Run-over-Run Delta
Compare Run N vs Run N-1 verdicts. Flag regressions (PASS→MARGINAL), improvements, and stalls. Haiku
output
audit/CORPUS_REINGESTION_AUDIT_RUN-N.md
25-doc scorecard table + verdict delta section. One file per run, appended over iterations.
G1
Human reviews scorecard. Decide: continue cycle or stop (converged). manual
3
Diagnose + Plan
Two-tier cluster→drilldown trace architecture. Triage by failure domain, trace root causes per cluster (not per document), selective drilldown only where cluster can’t explain. Checkpoint persistence enables cross-session resume. Then draft RFC, verify, build artifacts.
Stage 1 — Triage + Trace (token-efficient two-tier architecture):
corpus:trace → triage
Triage
Categorize each issue by failure domain (splitter, text_layer, converter, picture_ocr, verdict_logic, worker) and complexity (simple/complex). Only MARGINAL/FAIL/ERROR/regressed docs — PASS/stable excluded upstream. Sonnet
corpus:trace → cluster
Cluster Trace
One Opus agent per domain cluster (not per document). Groups issues by shared domain, finds the single root cause that explains ALL documents in that cluster. Uses /codebase-memory + Serena MCP strictly in parallel. If a document can’t be explained by the shared root cause, it’s flagged for drilldown. Opus
corpus:trace → drilldown
Document Drill-down
Per-document investigation only for docs flagged as ambiguous by cluster trace. Skipped entirely if all documents are explained at cluster level. Model tier routes by complexity. Sonnet (complex) / Haiku (simple)
checkpoint
Cross-Session Resume
Results persisted to .agents/checkpoints/diagnose-plan-runN/ after each phase (triage, cluster-traces, drilldown). Resume via args.resume_from: triage | cluster_trace | drilldown | traces. Avoids re-running expensive Opus work on context-limit interruptions. Haiku
Stage 2 — RFC Drafting + Verification (Opus-Fable loop):
corpus:plan
RFC Drafting
Opus groups merged trace findings into D-numbered decisions, drafts RFC with implementation plan, test strategy, and risks. Fable adversarially verifies (coverage, scoping, dependencies, contradictions, file accuracy). Opus re-drafts via Serena MCP tools only (replace_content / replace_in_files — Edit/Write forbidden). Max 2 rounds.
Opus draft · Fable verify
rfc-artifact-build
Design + Tasks Generation
Takes the verified RFC and produces design doc + implementation task plan with bidirectional anchor links. Uses reference templates from .agents/reference_files/.
Artifact destinations:
.agents/rfcs/NNN-<slug>.mdRFC document
.agents/designs/design-rfcNNN-<slug>.mdDesign document
.agents/tasks/tasks-rfcNNN-<slug>.mdImplementation tasks
.agents/checkpoints/diagnose-plan-runN/Trace checkpoints (resume points)
G2
Human approves the plan: RFC scope, task breakdown, wave grouping. manual
4
Build
Execute the task plan in dependency-ordered waves using a pipeline pattern (Sonnet build + Fable/Opus review per task). Between-wave 3-layer checkpoints verify quality. Supports start_wave resume to skip completed waves on re-entry.
swarm-builder → pipeline
Wave Execution (build + review pipeline)
Tasks within each wave execute in parallel via a two-stage pipeline:
Stage 1: Build — implement the task using /codebase-memory + Serena MCP. Sonnet
Stage 2: Review — code review against RFC decisions + design properties. Model tier scales with task complexity. Fable (complex) / Opus (medium)
corpus:mend
Test Repair
If L1 pytest fails, a dedicated repair agent diagnoses failures (real regression vs outdated assumption vs test bug), fixes, and re-runs. Sonnet
3-layer between-wave checkpoint (+ task file update):
L1 pytest — binary pass/fail gate Haiku
L2 Code review vs design doc — Code Architect agent as reviewer Fable / Opus 5
L3 Task acceptance criteria — verify done-when clauses, update tasks file via Serena MCP (replace_content) Fable / Opus 5
Model tier for L2/L3 scales with wave complexity — simple waves get Fable, complex changes escalate to Opus 5.
G3
All waves complete. Full test suite green. All 3 checkpoint layers pass. auto Fable
5
Sync + Commit
Sync Confluence-headed files first, then commit all changes. Confluence sync before commit ensures the synced state is captured in the commit.
corpus:cycle → shell
Confluence Sync
make confluence-local-sync — existing Makefile target, no LLM needed. Syncs all files with <!-- Space: CITRA --> metadata headers across .agents/rfcs/, .agents/designs/, .agents/tasks/, audit/.
corpus:cycle → git
Batched Commits + Push
Changes committed in 4 logical batches with conventional commit prefixes referencing the RFC:
Batch 1docs(rfc-NNN): RFC + design + tasks (.agents/)
Batch 2feat(rfc-NNN): Implementation (src/)
Batch 3test(rfc-NNN): Tests (tests/)
Batch 4docs(audit): Audit artifacts (audit/)
All batches pushed together. No Co-Authored-By lines or other trailers in commit messages.
G4
Confluence synced. All batches committed and pushed. Clean working tree. auto Haiku
After G4, the cycle loops back to Phase 1 (Ingest) with fixes applied. Auto-convergence triggers at G1 when scoring shows 0 FAIL + 0 ERROR + 0 regressions. The human retains override — convergence is a judgment call, not a hard threshold. Checkpoints in Phase 3 and start_wave in Phase 4 allow mid-run resume if context limits interrupt.

Artifact Flow

Skill Output Destination
corpus:score + corpus:diff Scorecard + delta audit/CORPUS_REINGESTION_AUDIT_RUN-N.md
corpus:trace Root-cause investigation Inline in RFC body (no separate file)
corpus:plan RFC document .agents/rfcs/NNN-<slug>.md
rfc-artifact-build Design + tasks .agents/designs/ + .agents/tasks/
make confluence-local-sync Confluence pages All files with <!-- Space: CITRA --> headers

Model Tier Routing

Haiku
Easy tasks
Gate checks (G0, G4). Log parsing. Programmatic verdict checks. Diff generation. L1 pytest checkpoint.
Sonnet
Medium tasks
Implementation. Subjective verdicts. Test repair. Builder agents in waves.
Opus
Complex tasks
RFC drafting. Root-cause tracing. Architecture decisions. Phase orchestration.
Fable
Super complex tasks
RFC verification. Wave checkpoints (L2, L3). G3 final verdict. Cross-system analysis.

Dispatch Context

Every sub-agent, workflow, and skill invocation in the cycle receives this context block verbatim. It lives in a single reference file so changes propagate everywhere without editing each skill.
Use /codebase-memory (CodeGraph Approach) and Serena MCP server (Proxy Server to relevant LSP's) for code exploration STRICTLY in parallel. Also, dispatch parallel sub-agents or Workflow for the analysis ahead. We use Fable model for super complex tasks, Opus model for complex tasks, Sonnet model for medium tasks and Haiku model for easy tasks ALWAYS. We refer to /mem-search for past decisions undertaken and If REQUIRED then only check for confusions and reconcile them with the user itself wherever required. When generating Artifacts, NEVER export them to CLAUDE. ALWAYS export them Locally either as Markdown or HTML When updating tasks files (.agents/tasks/tasks-*.md), ALWAYS use Serena MCP server (replace_content or replace_in_files) instead of Edit/Write tools. Serena provides LSP-aware safe edits that preserve file structure.
Reference file: .claude/dispatch-context.md
Each skill and workflow reads this file at dispatch time and injects it into every sub-agent prompt. Update once, applies everywhere — no need to paste the block manually.

How to Run

Command Phase What it does
/corpus-ingest Phase 1 Wipe stores, restart services, re-ingest full corpus, verify G0
/corpus-score-diff Phase 2 Pipeline: Haiku fetch + Sonnet judge per doc, diff vs prior run, write audit/CORPUS_REINGESTION_AUDIT_RUN-N.md
/corpus-diagnose-plan @audit/CORPUS_….md Phase 3 Triage → cluster trace (Opus) → drilldown (Sonnet/Haiku) → checkpoint → Opus drafts RFC → Fable verifies → build design + tasks. Supports resume_from.
/corpus-build @.agents/tasks/tasks-rfcNNN-….md Phase 4 Pipeline: Sonnet build + Fable/Opus review per task, 3-layer checkpoints, test mending. Supports start_wave resume.
/corpus-sync-commit Phase 5 Confluence sync, 4 batched git commits (no co-author trailers), push, verify G4
/corpus-cycle Full loop All 5 phases end-to-end, pauses at G1 and G2 for human review

Decisions Log

Key architectural and process decisions made across the project lifecycle, sourced from claude-mem observations and project memory. Organized chronologically.

Architecture & Pipeline

2026-06 · RFC-003 / RFC-005
PDF Extraction: Markdown-First + Docling CPU
PyPDF2 garbles German insurance PDFs — root cause is text extraction, not OCR. Adopted markdown-first extraction via pymupdf4llm. Docling-CPU is the config-gated converter (PDF_CONVERTER=docling, force CPU on darwin). pymupdf4llm drops the fl-ligature (Haftpflicht→Haftpficht); Docling fixes it. Docling MPS-only was NO-GO on Apple Silicon.
2026-06-12 · RFC-004 · USER-LOCKED
Granite-258M REJECTED for All Future Implementations
gpt-4.1 vision: DPI-unstable hierarchy hallucination → validates flat-doc-success route. VLM stays off by default. Granite-258M permanently rejected: 2.9 GB RSS, 38 min/page on CPU, flat-only output. RFC-004 D1/D2 adopted: deterministic-first VLM-escalation cascade (VLM_MODE=disabled default) + hybrid engine (frontier gpt-4.1 vision via OPENAI_BASE_URL; self-hosted Apache-2.0 residency floor).
2026-06-12 · RFC-004
Flat Docs: SUCCESS, Not Rejected
Clean-text-layer docs with no hierarchy are processed as SUCCESS — matches all 8 surveyed peers (Textract, Azure DI, Google Doc AI, Docling, Unstructured, LlamaParse, Reducto). "Flat" and "garbled" are orthogonal. Flat outcome: status=done + content_class ∈ {flat_table, flat_kv, flat_prose, flat_mixed}, persisted as processed/<doc_id>.flat.json; validate_tree() never called.
2026-06 · AGPL
AGPL Has THREE Pullers, Not One
pymupdf (AGPL) enters via pymupdf4llm AND docling-hierarchical-pdf AND the pageindex fork. pymupdf4llm now moved behind agpl-fallback extra (landed). Verify other two pullers before declaring venv clean. MIT escape: Docling.

Corpus Remediation (RFC-018 / RFC-019)

2026-07-27 · RFC-018
D0–D3: Marker Count, Text-Layer Probe, Arabic RTL, Garble Gate
D0 marker-count fix: WORKING. D1 text-layer skip: WORKING. D2 Arabic RTL hardening: WORKING. D3a garble probe: PARTIAL (Latin-gibberish gap on document ‎597). D3b per-node garble: WORKING. Full corpus validation: 25/25 processed → 23 stored (11 PASS, 9 MARGINAL, 3 FAIL), 2 errors.
2026-07-27 · RFC-019
D0–D4: Five Corpus Reingestion Fixes
5 fixes from 25-doc audit (12P/9M/3F/1E): D0 landed, D1 uncommitted, D2/D3/D4 pending. 14 tasks, 4.5 person-days estimated.

Content Recovery & Verdict Hardening (RFC-021 / RFC-023)

2026-07-28 · RFC-021
Verdict Quick-Fixes: QF1–QF4
QF1 accepts imperfect but useful tree output. QF2a/QF2b/QF2c tighten or defer garble checks. QF4 LEGACY_VERDICT_ENABLED env var provides rollback lever to restore pre-RFC-021 behavior. Cross-fix interaction risks flagged: QF2c+QF4 could PASS numeric-junk docs.
2026-07-28 · RFC-017
OCR Image Block Decoupling: Page Coverage + Standalone Image
D0: Skip regions exceeding 60% page area in _recover_picture_text() — full scanned pages handled by page-level OCR, not per-picture cropping. PICTURE_PAGE_COVERAGE_THRESHOLD env var (default 0.6). D1: Standalone image branch never calls splice_figure_markers() or _enrich_image_blocks() — chart content lost entirely. Fix: create synthetic PictureResult after image_to_markdown().
2026-07-29 · RFC-023
D0–D11: Content Recovery & Verdict Hardening (12 Decisions)
Run 6 corpus reaudit (25 docs): 11 PASS / 4 MARGINAL / 9 FAIL / 1 ERROR. 12 decisions across 3 themes:
A. Garble-aware recovery — D0: garble-check in _text_layer_has_content; D1: ordinal marker splicing; D2: decorative-icon bbox filter; D11: image-dominant OCR escalation.
B. Verdict correctness — D3: strip HTML comments before garble tokenization; D4: content-quality guard on cat_b_promoted; D5: prefer synthetic structure over rejected tree.
C. Pipeline resilience — D6: page rotation correction; D7: Tesseract-on-raster VLM-crash fallback; D8–D10: verdict hysteresis and tuning. Projected Run 7: 18–20 PASS (up from 11).

Process & Workflow Conventions

2026-07-20
Model Tier Assignment Convention
Tiered model selection established for all sub-agent and workflow dispatching: Fable super complex tasks (RFC verification, wave checkpoints, G3 verdict) · Opus complex tasks (RFC drafting, root-cause tracing, architecture) · Sonnet medium tasks (subjective verdicts, test repair) · Haiku easy tasks (programmatic scoring, shell commands).
2026-07-20
Parallel Code Exploration: CodeGraph + Serena MCP
All code exploration must use /codebase-memory (CodeGraph) and Serena MCP server (proxy to relevant LSPs) strictly in parallel. Established as mandatory dispatch context for every sub-agent invocation.
2026-07-28
Dispatch Context Conventions
.claude/dispatch-context.md created as centralized governance document, included verbatim in every sub-agent/workflow/skill prompt. Rules: parallel CodeGraph + Serena exploration, tiered model selection, local-only artifact export (never to Claude), Serena MCP for task file edits, /mem-search for past decisions.
2026-07-27
Task Document Markdown Conventions
Phase-based structure with strict anchor-link cross-referencing. No ###/#### headings inside Tasks section — nested checkbox lists only. Every task has _Requirements:_ line with pipe-separated clickable links. All cross-references must be clickable markdown anchor links, no bare text.
2026-07-27
Corpus Trace Token Efficiency Redesign
Phase 3 trace restructured from per-document Opus/Sonnet to cluster-level Opus + selective Sonnet/Haiku drilldown. Skip PASS docs in Phase 3; focus on code changes causing regressions; prefer simple solutions over complex approaches.
2026-07-29
No Co-Authors in Corpus Sync-Commit
Corpus sync-commit workflow (.claude/workflows/corpus-sync-commit.js) must NOT include any Co-Authored-By lines or Generated with trailers in any of the 4 batched commit messages. Each batch agent explicitly instructed to omit all co-author attribution.
2026-07-28
Skills + Workflows Architecture (over hooks/plugins)
Corpus toolset built as project-local Claude Code Skills (markdown entry points in .claude/skills/) + Workflows (JS scripts in .claude/workflows/) rather than hooks or plugins. 7 skills + 6 workflows. Full loop has 5 phases with human-in-the-loop gates at G1 and G2. Shared dispatch-context.md propagates conventions to all sub-agents.
2026-07-28
Corpus Namespace Convention (corpus: prefix)
All corpus skills use a corpus: namespace prefix: /corpus:score, /corpus:diff, /corpus:trace, /corpus:plan, /corpus:mend, /corpus:cycle. Skill directories match workflow names. Gated pipeline with numbered runs and RFC-based task planning.
2026-07-28
File Organization: One-File-Per-Run + Trace Inlined
Audit scorecards moved from append-style to one-file-per-run (CORPUS_REINGESTION_AUDIT_RUN-N.md). Root-cause investigation traces are inlined directly into the RFC produced by corpus:plan, eliminating separate trace files in audit/ or .agents/state/.
2026-07-29
Serena MCP Enforced for RFC Re-Drafting
Opus re-drafting step (after Fable verification) restricted to Serena MCP tools only (replace_content / replace_in_files). Edit/Write tools forbidden for RFC file modifications. Same constraint applies to L3 checkpoint task file updates.
2026-07-29
Checkpoint Persistence + Cross-Session Resume
Phase 3 (Diagnose + Plan) persists checkpoints to .agents/checkpoints/diagnose-plan-runN/ after each sub-phase: triage, cluster-traces, drilldown. Resume via args.resume_from avoids re-running expensive Opus cluster trace work on context-limit interruptions. Phase 4 supports start_wave to skip completed waves.
2026-07-28
Auto-Convergence Criteria
Cycle auto-converges when scoring produces 0 FAIL + 0 ERROR + 0 regressions. At G1, if converged, the orchestrator reports convergence and stops. Human retains override: convergence is a judgment call at G1, not a hard threshold.

Guardrails & Lessons Learned

2026-06 · RFC-002 lesson
Verify Source Before Asserting Defects
Must read file:line before any code [FIX] claim in an RFC or queue. Established after RFC-002 fabrication incident where asserted defects did not exist in the actual code.
2026-07-17
Fabricated Corpus Report Detected
DOC_STORE_CORPUS_REPORT.md verdict table was FABRICATED. Real MinIO meta.json showed 11 PASS / 12 MARGINAL / 2 FAIL — not the claimed 15 / 10 / 0. Always verify against source data.
2026-07
Never Export Artifacts to Claude
Artifacts must always be written locally as .md or .html files. Never use the Claude Artifact tool for export. This is a hard rule in the dispatch context.
2026-07
OCR/Image-Block Conflation Confirmed
feat/image-block-picture-ocr branch conflates page-level OCR with per-picture enrichment. OCR text reclassified from prose to image blocks. Standalone images lose chart content entirely. P0–P5 fix plan documented at audit/OCR_IMAGE_BLOCK_CONFLATION_INVESTIGATION_2026-07-27.md.

Infrastructure

2026-07
Worker Deploy Rollout Fix
pageindex-mcp-worker rollout times out: new replicas stuck Pending (unschedulable) on single-node k3s, NOT a crash. Worker maxSurge:1/maxUnavailable:0 needs room for 2 pods; node over-committed. Fix: maxSurge:0/maxUnavailable:1 + bigger node.
2026-06 · PR #11
Langfuse Tracing (LLM-02)
Merged. Gotcha: litellm langfuse_otel uses a PRIVATE OTel provider (skip_set_global) → needs client.flush_litellm_tracing(); langfuse client flush alone won't reach it. Deploy manifests live in sibling hetzner-deployment-service repo.

Last updated: 2026-07-29 · Sourced from claude-mem observations + project memory