← All craftbooks

OCR a Folder of Scans

Media: imagesevalv1.0.0released 2026-06-05workflow: build-loop

Extract the text from a folder of scanned documents or photographed pages into clean, structured text — preserving reading order, paragraph breaks, and per-file provenance — then verify the extraction against the source images. Scope FIRST the languages, output structure (one file per scan vs a combined doc), and how to handle tables/columns/low-confidence regions, because OCR quality is dominated by handling layout and flagging uncertainty; then run extraction and verify a sample reads correctly. Covers OCR, text extraction, scanned documents, digitizing paper, receipt/invoice text, and image-to-text.

Steps

Entry step: scope. Each step names the specialist role it wants; the full working prompt is expandable.

  1. Scope the extractionplannerentry

    languages, output structure, layout & confidence rules

    Show working prompt
    1) List the scan folder and note formats and roughly what the pages are (typed, handwritten, mixed, tables). 2) Decide the language(s) for OCR. 3) Lock the output structure: one .txt/.md per source (named to match) and/or a combined document, with each block tagged by source filename for provenance. 4) Decide layout handling — preserve paragraph breaks and reading order, how to render tables (markdown tables or labeled rows), and how to flag low-confidence or unreadable regions (e.g. [illegible]). 5) Write an acceptance-criteria checklist: 'every scan produces an output', 'reading order and paragraph breaks are preserved', 'tables are not scrambled into a single line', 'low-confidence text is flagged not silently dropped', 'output is plain readable text, not garbled'. 6) Record scope + checklist via write_task_note AND to notes/scope.md.
  2. Extract the textdeveloper

    OCR each scan into structured text

    Show working prompt
    1) Read scope.md. 2) For each scan, run OCR — prefer a real OCR engine (Tesseract) or the vision capability reading the image directly. 3) Preserve reading order and paragraph structure; for multi-column pages, read column-by-column not left-to-right across columns. 4) Render tables as the agreed structure rather than collapsing them. 5) Flag uncertain text with the agreed marker instead of inventing words. 6) Write each output to the agreed path with source provenance, and assemble the combined doc if requested. 7) Keep a running count of scans processed. write_task_note the output location and counts. Good looks like: text a human could read as the original document, with uncertainty honestly flagged.
  3. Verify the extractionreviewer

    check a sample of outputs against the source images

    Show working prompt
    1) Re-read scope.md's checklist. 2) Confirm output count equals scan count (PASS/FAIL). 3) Pick 3-4 scans, open BOTH the image and its extracted text, and compare: is the text accurate, in correct reading order, with paragraphs/tables intact (PASS/FAIL)? 4) Confirm low-confidence regions are flagged, not silently wrong or dropped. 5) Confirm provenance — each block traces to its source file. 6) Write a verification note with PASS/FAIL per criterion and the specific files you checked. On a loop-back the extractor fixes the flagged files. write_task_note the result.
  4. Evaluatereviewer

    Grade the deliverable against every acceptance criterion. All pass → finish; any fail → loop back and fix the gap.

    Show working prompt
    1) Open out/ and confirm every scan has an output (PASS/FAIL). 2) For 3-4 files, open the source image alongside the extracted text and check accuracy, reading order, and that tables/columns are not scrambled (PASS/FAIL). 3) Confirm uncertain text is flagged, not silently dropped or hallucinated. 4) Confirm provenance back to source files. 5) Reconcile verify.md's claims with what you observe. 6) Write PASS/FAIL per criterion. Inaccurate/garbled extraction → loop back to extract.
    
    Then route — this is the whole point of the loop:
    
    - **Every criterion PASSES →** call `advance_task_step({ ref, stepId: "evaluate", next: "finish" })`.
    - **Any criterion FAILS →** write the specific gaps to notes, then call `advance_task_step({ ref, stepId: "evaluate", next: "extract" })` to loop back. The builder fixes exactly those gaps.
    
    Never route to `finish` while any criterion is unmet. The build phase's completion gate already blocked a grossly-incomplete deliverable; your job is the judgment an automated check cannot make (does it actually work, read well, look right). After ~3 unproductive loops, stop and report DONE_WITH_CONCERNS so the user can step in.
  5. Finishdeveloper

    All acceptance criteria met. Stamp a short summary and report DONE.

    Show working prompt
    Every acceptance criterion passed. Write a one-paragraph DONE summary to task notes via `write_task_note`: what was built, the deliverable path(s), and a one-line confirmation that each criterion is met. Then report DONE.

Triggers

Phrases that suggest this craftbook to a crew.

Source

View this craftbook on GitHub · MIT license