- Chunked PDF parsing now fans out across Celery workers (issue #1960). Large documents are split into page-range chunks parsed by independent `parse_document_chunk` tasks that write results to storage; a `reassemble_and_save_chunks` chord callback streams those results back one at a time and persists. `ingest_doc` dispatches the chord via `self.replace` for large docs (non-eager); small docs, non-chunking parsers, and eager mode keep the synchronous in-process path. New: `opencontractserver/pipeline/chunk_artifacts.py`, `opencontractserver/pipeline/base/chunk_reassembler.py` (incremental `ChunkReassembler`), `opencontractserver/tasks/chunk_tasks.py`. Bounds memory to one chunk in flight per worker and one chunk result at a time in the reassembler. Chunk tasks re-load parser kwargs from the DB, so no secrets traverse the broker; permanent parse errors fail fast (no retry) while transient errors retry via Celery.
