# Internal: Extract Stage ## Responsibility `extract` runs after `trim` and before `render`. It converts the canonical `narratio.transcript.final_trimmed` JSON into configured Notarius lane artifacts. An omitted or disabled Notarius section makes the stage explicitly self-skip with reason `notarius_disabled`, no outputs, and no Notarius runner. The external protocol is documented in the [Notarius integration contract](../integrations/notarius.md). Configuration fields belong in [Configuration](../config.md), and physical paths and force procedures belong in [Operations](../operations.md). ## Lifecycle `internal/stage/extract.go`: 1. resolves the final trimmed transcript from the shared artifact catalog; 2. resolves and fingerprints the Notarius invocation contract; 3. creates a run-local staging directory and invokes the injected `notarius.Runner`; 4. validates the successful receipt, confined index, configured required lane descriptors, and regular payload files; 5. atomically promotes the complete bundle to its immutable durable location; 6. records one non-selectable `notarius_index` output and one selectable `notarius_lane` output per configured lane; and 7. registers each lane as `narratio.extraction.` for downstream Scriptorium and publish resolution. Lane records retain checksum, contract, producer run ID, and Notarius system, run, pipeline, and lane provenance. Stage metadata retains the durable bundle root, receipt, diagnostic paths, rejection/warning summaries, producing Narratio run ID, and invocation fingerprint. Validation completes before promotion, so a rejected result cannot expose a partial durable bundle. Any executed extraction outcome that replaces a different effective outcome marks succeeded downstream stages stale. Repeating the same disabled self-skip with no outputs is stable and does not repeatedly invalidate downstream stages. ## Resume Validation `internal/stage/extract_resume.go` permits a skip only when the existing stage record succeeded and still matches the current invocation fingerprint. The fingerprint covers the resolved executable and config paths, pipeline ID, timeout, working directory, and sorted configured output contracts. The validator then checks the producing run identity, canonical immutable bundle root, path confinement and absence of symlink components, receipt identity, exactly one canonical index, the exact configured source set, contracts and provenance, regular-file status, and stored checksums. Missing or obsolete results are non-resumable and run again; unsafe filesystem conditions return an error rather than silently accepting or replacing data. The fingerprint cannot observe files imported by Notarius configuration, profile contents, prompt/module definitions, or other transitive inputs. Operators must force extraction after changing any such input. ## Failure Behavior Adapter startup, timeout, nonzero exit, receipt decoding, path confinement, index compatibility, required-lane rejection, payload inspection, checksum, or promotion errors fail the stage through ordinary manifest transition handling. Stdout receipt and stderr diagnostics remain separate. Downstream stages are not given selectable extraction sources unless the complete configured result has passed validation and promotion. When a replacement attempt begins, the current session-stage record no longer advertises payload from the previous success. A failed replacement therefore has no current outputs, logs, generated configuration references, or metadata, while the earlier invocation manifest and immutable promoted bundle remain available for audit and recovery. ## Implementation And Focused Tests - Stage execution, selection, and resume validation: `internal/stage/extract.go`, `internal/stage/extract_resume.go`, `internal/stage/extract_test.go` - Subprocess boundary: `internal/adapters/notarius/subprocess.go`, `internal/adapters/notarius/subprocess_test.go` - Catalog hydration: `internal/artifacts/extraction_catalog.go`, `internal/artifacts/extraction_catalog_test.go` - Composition and downstream behavior: `internal/app/runner_test.go`, `internal/stage/analyze_test.go`, `internal/stage/publish_test.go`