Extraction Execution Strategy
Controls how the PropositionPipeline dispatches the stateless per-chunk extraction stage. Implementations choose serial or concurrent execution; the resolution stage (entity resolution) always runs serially regardless of the strategy, preserving cross-chunk entity identity.
Contract
Input order is preserved: the returned list has exactly
chunks.sizeelements andresult[i]corresponds tochunks[i](ornullif extraction ofchunks[i]failed).Failure is a
nullslot: whenextract(chunk)throws, that slot becomesnullrather than propagating the exception. The pipeline maps anullslot to a ChunkPropositionResult.Failed. No element is ever dropped or reordered.
Executor ownership
Each implementation owns its execution mechanism. The execute signature intentionally does not mention ExecutorService — any executor is an injected implementation detail. A caller-supplied executor is never shut down by the strategy — its lifecycle stays the caller's. When a strategy creates its own pool (the no-executor constructors), that pool is the strategy's to clean up: both concurrent strategies are AutoCloseable, and close shuts down only an internally-created pool.
Thread-safety gate for production
The default is SerialExtractionStrategy (no concurrency). Before switching to ParallelExtractionStrategy or BatchedExtractionStrategy with batchSize > 1, verify that the Ai implementation backing your PropositionExtractor is thread-safe for concurrent extract() calls. Until then, BatchedExtractionStrategy(batchSize = 1) is the safe degrade-to-serial path.
Note: this is a plain interface rather than a fun interface because Kotlin SAM conversion does not support abstract methods with their own type parameters (fun <T> execute(...)).