
Pdf Brain Ingest
- 39 installs
- 61 repo stars
- Updated August 4, 2026
- joelhooks/joelclaw
Ingest and batch-reindex PDF/Markdown docs into joelclaw's memory via a durable staged Inngest pipeline with NAS artifacts and embeddings.
About
Ingests PDF/Markdown/TXT files into joelclaw's docs memory through a durable, resumable Inngest pipeline with OTEL verification. A developer uses it to add docs, run batch reindexes, reconcile coverage, or recover stuck runs.
- Staged artifact-chain pipeline: convert, classify/summarize, chunk, index with nomic-embed 768-dim vectors
- Durable NAS artifacts make each stage resumable, with batch reindex, reconcile, and recovery commands
Pdf Brain Ingest by the numbers
- 39 all-time installs (skills.sh)
- Ranked #1,147 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/joelhooks/joelclaw --skill pdf-brain-ingestAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 39 |
|---|---|
| repo stars | ★ 61 |
| Last updated | August 4, 2026 |
| Repository | joelhooks/joelclaw ↗ |
What it does
Ingest and batch-reindex PDF/Markdown docs into joelclaw's memory via a durable staged Inngest pipeline with NAS artifacts and embeddings.
Files
PDF Brain Ingest v2 (ADR-0234)
Staged artifact-chain pipeline with durable NAS storage, nomic embeddings, and workload queue orchestration.
Pipeline v2 Architecture
PDF (source, immutable)
→ Stage 1: CONVERT — opendataloader-pdf → {docId}.md (NAS artifact)
→ Stage 2: CLASSIFY + SUMMARIZE — taxonomy + LLM summary → {docId}.meta.json (NAS artifact)
→ Stage 3: CHUNK — markdown-native headings, no overlap → {docId}.chunks.jsonl (NAS artifact)
→ Stage 4: INDEX — upsert to docs + docs_chunks_v2 (nomic-embed-text-v1.5, 768-dim)Key properties:
- Durable: artifacts on NAS RAID5, survive reboots/crashes
- Resumable: each stage checks for existing artifacts, skips if present
- Recoverable: re-run any stage from existing artifacts without re-extracting
- Observable: OTEL event per stage per book
Artifacts dir: /Volumes/three-body/docs-artifacts/{docId}/
{docId}.md— structured markdown extraction{docId}.meta.json— taxonomy, summary, metadata{docId}.chunks.jsonl— chunk records, one per line
Core Workflow
1) Preflight
joelclaw status
joelclaw docs statusStatus now shows both v1 and v2 collection stats plus artifact availability.
2) Single File Ingest (v1 pipeline)
joelclaw docs add "/absolute/path/to/file.pdf"
joelclaw docs add "/absolute/path/to/file.pdf" --title "Title" --tags "tag1,tag2" --category programming3) Single File v2 Reindex (artifact pipeline)
joelclaw docs reindex-v2 "/absolute/path/to/file.pdf"
joelclaw docs reindex-v2 "/absolute/path/to/file.pdf" --title "Title" --skip-existingFires docs/reindex-v2.requested → 4-stage artifact pipeline → NAS artifacts + docs_chunks_v2.
4) Batch Reindex (full library)
# Reindex all PDFs from NAS /Volumes/three-body/books/
joelclaw docs batch-reindex --skip-existing
# Reindex from existing Typesense docs collection
joelclaw docs batch-reindex --from-collection --skip-existingFires docs/reindex-batch.requested → scans NAS/collection → dispatches individual reindex-v2 events in batches of 10, concurrency 3.
--skip-existing skips books that already have all 3 artifacts on NAS (default true).
5) Monitor Progress
# Artifact count on NAS
ls /Volumes/three-body/docs-artifacts/ | wc -l
# v2 collection chunk count
joelclaw docs status
# OTEL events from pipeline
joelclaw otel search "docs.reindex" --hours 4
joelclaw o11y session system-bus --hours 4
# Individual run trace
joelclaw runs --count 10
joelclaw run <run-id>6) Inspect Artifacts
# Read the extracted markdown
joelclaw docs markdown <doc-id>
# Read the summary + taxonomy metadata
joelclaw docs summary <doc-id>
# Or directly on NAS
cat /Volumes/three-body/docs-artifacts/<docId>/<docId>.md
cat /Volumes/three-body/docs-artifacts/<docId>/<docId>.meta.json | jq
wc -l /Volumes/three-body/docs-artifacts/<docId>/<docId>.chunks.jsonl7) Retrieval from v2
# Search uses docs_chunks_v2 (nomic 768-dim) by default
joelclaw docs search "distributed consensus" --limit 8
# Context expansion
joelclaw docs context <chunk-id> --mode snippet-window
joelclaw docs context <chunk-id> --mode parent-section
joelclaw docs context <chunk-id> --mode section-neighborhood8) Coverage Reconcile
joelclaw docs reconcile --sample 209) Recovery
If the batch stalls or books fail:
- Inngest retries each step automatically (default retry policy)
--skip-existingmeans re-firing the batch only processes unfinished books- Check OTEL for errors:
joelclaw otel list --level error --hours 4 - Individual retry:
joelclaw docs reindex-v2 "/path/to/failed.pdf"
Extraction Details
- Primary: opendataloader-pdf v2.0.0 (Java-based, #1 in benchmarks, 0.90 accuracy)
- Fallback: pypdf (basic text extraction if Java unavailable)
- Requires: Java 11+ (OpenJDK 25 installed on panda, PATH configured in worker start.sh)
- Speed: ~2.5s per book on M4 Pro
Embedding Model
- v2: nomic-embed-text via ollama (GPU-accelerated on M4 Pro, 768-dim, retrieval-tuned). Pre-computed at ingest time, stored as raw float[] vectors. ~150x faster than Typesense CPU auto-embed.
- v1:
ts/all-MiniLM-L12-v2— 384-dim, general-purpose, Typesense auto-embed (legacy, still indocs_chunks) - Ollama runs on panda at
localhost:11434. System-bus-worker (host process) embeds at ingest time.
Chunking Strategy (ADR-0234)
- Markdown-native heading detection (
#markers, not heuristics) - Recursive splitting within sections exceeding target tokens
- No overlap (arxiv R100-0 finding: 45% higher precision)
- Two-level hierarchy: section chunks + snippet sub-chunks
- heading_path derived from actual markdown heading levels
- Context inheritance: retrieval_text includes
[DOC: title] [SUMMARY: ...] [PATH: heading > path] [CONCEPTS: ...]
Acquisition Pipeline (aa-book → ingest)
joelclaw send pipeline/book.download -d '{
"query": "designing data-intensive applications",
"format": "pdf",
"reason": "library expansion"
}'Downloads via aa-book → NAS backup → fires docs/ingest.requested for immediate processing.
Inngest Events
| Event | Function | Purpose |
|---|---|---|
docs/ingest.requested | docs-ingest | v1 pipeline (single file) |
docs/reindex-v2.requested | docs-reindex-v2 | v2 artifact pipeline (single file) |
docs/reindex-batch.requested | docs-reindex-batch | Batch orchestrator (all PDFs) |
docs/backlog.requested | docs-backlog | Legacy manifest-based backfill |
docs/enrich.requested | docs-enrich | Re-enrich metadata for existing doc |
pipeline/book.download | book-download | Acquire + ingest new book |
interface:
icon_small: "./assets/small-logo.svg"
icon_large: "./assets/large-logo.png"
<svg width="16" height="16" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="JoelClaw icon">
<defs>
<clipPath id="circle-clip">
<circle cx="256" cy="256" r="248" />
</clipPath>
</defs>
<circle cx="256" cy="256" r="248" fill="#0a0a0a" />
<g clip-path="url(#circle-clip)">
<path fill="#ff1493" d="M175.656 22.375l-48.47 82.094c-23.017 4.384-43.547 11.782-60.124 22.374-24.436 15.613-40.572 37.414-45.5 67.875-4.79 29.62 1.568 68.087 24.125 116.093 93.162 22.88 184.08-10.908 257.25-18.813 37.138-4.012 71.196-.898 96.344 22.97 22.33 21.19 36.21 56.808 41.908 113.436 29.246-35.682 44.538-69.065 49.343-99.594 5.543-35.207-2.526-66.97-20.31-95.593-8.52-13.708-19.368-26.618-32-38.626l14.217-33-41.218 10.625c-8.637-6.278-17.765-12.217-27.314-17.782l-7.03-59.782-38.157 37.406c-12.418-5.186-25.184-9.804-38.158-13.812l-8.375-71.28-57.625 56.5c-9.344-1.316-18.625-2.333-27.812-2.97l-31.094-78.125zM222 325.345c-39.146 7.525-82.183 14.312-127.156 11.686 47.403 113.454 207.056 224.082 260.125 87-101.18 33.84-95.303-49.595-132.97-98.686z" />
</g>
</svg>
PDF-Brain Ingest Operator Guide (Joelclaw)
Date: 2026-02-23 Scope: Ingest new pdf/md files into the docs + docs_chunks memory pipeline on joelclaw.
0) aa-book End-to-End Acquisition (Recommended for books)
Queue acquisition + inference + download + ingest in one durable workflow:
joelclaw send pipeline/book.download -d '{
"query": "designing data-intensive applications",
"format": "pdf",
"reason": "memory backfill"
}'Current runtime behavior:
aa-book downloadkeeps the local file inoutputDirfor docs ingest.- The workflow then attempts a non-fatal NAS backup to
/volume1/home/joel/books/<year>/.... docs/ingest.requestedprefers the localfilePathwhen present, so NAS outages do not block ingest.
Optional direct MD5 (skip search/inference):
joelclaw send pipeline/book.download -d '{
"md5": "0123456789abcdef0123456789abcdef"
}'1) Preflight
joelclaw status
joelclaw inngest status
joelclaw docs statusIf worker registration looks stale:
joelclaw inngest sync-worker --restart2) Ingest a Single File
Queue one file:
joelclaw docs add "/absolute/path/to/file.pdf"
joelclaw docs add "/absolute/path/to/file.md"Optional metadata:
joelclaw docs add "/absolute/path/to/file.pdf" \
--title "Readable Title" \
--tags "manifest,catalog-fill" \
--category programmingNotes:
- Use absolute paths.
- Supported file types are
pdf,md,txt. - Ingest writes document records into
docsand hierarchical section/snippet chunks intodocs_chunks.
3) Monitor Runs
joelclaw runs --count 20 --hours 1
joelclaw run <run-id>Healthy run shape for docs-ingest:
validate-fileextract-textclassify-taxonomyensure-docs-collectionsupsert-documentchunk-and-indexemit-completedcleanup-text-artifactFinalization
4) Verify Index + Retrieval
joelclaw docs list --limit 20
joelclaw docs show <doc-id>
joelclaw docs search "your query"
joelclaw docs context <chunk-id> --mode snippet-window5) Reconcile Coverage Against Manifest
Use dual coverage to avoid false missing churn:
joelclaw docs reconcile --sample 20This reports:
path_exactcoverage: exactnas_pathmatch.content_equivalentcoverage: category-insensitive book path equivalence.
Interpretation:
- If
content_equivalent > path_exact, missing churn is mostly path-variant noise. falseMissingChurnsample shows paths that look missing by exact path but are content-equivalent matches.
6) Path Alias Behavior (Important)
Docs now store both:
nas_path(canonical)nas_paths[](all known aliases for same doc id/content)
Result:
- Re-ingesting the same content via a different absolute path appends to
nas_paths[]. - Canonical
nas_pathstays stable, preventing category/path flip-flop.
7) OTEL Checks
Core ingest telemetry:
joelclaw otel search "docs.file.validated" --hours 1
joelclaw otel search "docs.taxonomy.classified" --hours 1
joelclaw otel search "docs.chunks.indexed" --hours 1
joelclaw otel search "docs.path.aliases.updated" --hours 24Timeout signal (taxonomy subprocess guard):
joelclaw otel search "docs.taxonomy.classify.timeout" --hours 248) Troubleshooting
Stuck running at validate step with NAS paths
Symptom in run trace:
validate-fileretries/fails withEINTR: interrupted system call, open '/Volumes/three-body/...
Find quickly:
joelclaw otel search "EINTR: interrupted system call" --hours 1Mitigation:
- Requeue affected files once NAS path is stable.
- Avoid blasting high-concurrency retries on flaky mounts.
- Keep observing run queue and OTEL until the file validates cleanly.
Finalization/network anomalies
joelclaw run <run-id>
joelclaw logs worker --lines 120
joelclaw otel search "docs." --hours 19) Useful Maintenance Commands
joelclaw docs enrich <doc-id>
joelclaw docs reindex --doc <doc-id>
joelclaw docs reindexUse reindex to normalize earlier runs after taxonomy/path logic changes.