# Stage: render ## Purpose Render Markdown transcript artifacts from normalized JSON transcripts via Seriatim. It runs after `trim` and before `extract` in the canonical sequence. Render and extract are independent sibling consumers: replacing render output does not invalidate extraction, but it does invalidate succeeded analysis and delivery records that may consume rendered transcripts. ## Inputs - `narratio.transcript.final` (`transcripts/final.json`) - `narratio.transcript.final_trimmed` (`transcripts/final.trimmed.json`) ## Outputs - `narratio.transcript.final_markdown` -> `transcripts/final.md` - `narratio.transcript.final_trimmed_markdown` -> `transcripts/final.trimmed.md` ## Key Behavior - uses `pipeline.render` settings (enabled/format/title/booleans). - resolves inputs manifest-first, then canonical fallback. - writes run-local outputs first, then materializes canonical session outputs. - records input provenance, output paths, adapter metadata, logs, and generated config refs. - when `pipeline.render.enabled=false`, completes successfully with no outputs and records explanatory metadata. This is not an explicit self-skip: both manifests record success. Because enablement is fingerprinted, enabling render later automatically makes the prior result non-resumable. ## Failure Semantics - missing normalized input fails with normalize rerun guidance. - missing trimmed input fails with trim rerun guidance. - adapter/subprocess failure fails stage. - empty render output files fail validation. ## Invariants - only `format: markdown` is supported. - render stage owns production of built-in Markdown transcript sources. ## Resume Semantics The versioned semantic fingerprint covers enablement, final format, resolved title (including the session-title fallback), timestamp, segment-ID and metadata inclusion, both canonical input identities, and both Markdown output identities. Seriatim's executable, timeout, and report behavior are operational and do not invalidate rendered transcripts. A render-only change leaves the independent `extract` sibling reusable while invalidating their shared downstream consumers. ## Related Contracts And Tests - [Seriatim](../integrations/seriatim.md) owns render subprocess behavior. - [Configuration](../config.md#pipeline) owns render fields and defaults. - Implementation and tests: `internal/stage/render.go`, `internal/stage/render_test.go`, `internal/stage/semantic_contracts_refinement.go`