# Render Command Roadmap ## Purpose and scope This roadmap defines the future implementation plan for a top-level `seriatim render` command. The first supported render format will be Markdown. `render` should consume an existing normalized seriatim JSON artifact and emit a human-facing presentation artifact. JSON remains the canonical machine-readable seriatim artifact. Markdown output is disposable and reproducible from JSON. This is a roadmap document. Do not update current-behavior docs until `render` is implemented. The active architecture policy for this repository is `docs/policy/architecture.md`; `docs/architecture.md` does not exist in this checkout. ## Non-goals The first implementation must not: - accept raw WhisperX JSON input; - run merge, trim, normalize, overlap resolution, coalescing, autocorrect, or other merge-time transformations; - change existing JSON artifact schemas; - implement custom templates; - implement Markdown-to-JSON round-tripping; - implement paragraph or speaker-turn coalescing; - implement SRT, VTT, TXT, HTML, or other non-Markdown renderers; - add render report output; - expose internal category labels, overlap metadata, or debug provenance by default. Paragraphing, speaker-turn grouping, additional render formats, custom templates, and render reports may be considered later after the Markdown renderer is stable. ## User-facing UX Initial command: seriatim render --input-file transcript.json --output-file transcript.md --format markdown Required flags: | Flag | Description | | --- | --- | | `--input-file` | Existing normalized seriatim JSON artifact. | | `--output-file` | Rendered output path. | | `--format` | Public output format name. Initially only `markdown`. | Initial optional flags: | Flag | Default | Description | | --- | --- | --- | | `--title` | `Transcript` | Markdown document title. | | `--include-timestamps` | `true` | Include segment start/end timestamps. | | `--include-segment-ids` | `false` | Include segment IDs for reference. | | `--include-metadata` | `false` | Include artifact metadata block. | Use public CLI terminology `format`. Use internal implementation terminology `renderer`. ## Input and output contracts Input: - Must be an existing seriatim JSON output artifact. - Must validate as one of the current public schemas: `seriatim-minimal`, `seriatim-intermediate`, or `seriatim-full`. - Must not be interpreted as raw merge input or WhisperX JSON. - Must not be transformed semantically before rendering. Output: - Initial format is Markdown. - The output file is presentation-oriented, not canonical data. - Output should be overwritten consistently with existing file-output behavior unless implementation finds a conflicting repository policy. - Markdown output should be deterministic for identical input and render config. Render model: - Normalize all supported input schemas into a small internal render model. - Segment fields should include ID, start, end, speaker, text, and categories. - Full-schema-only fields such as source/provenance and overlap groups should not be required by renderers. ## Markdown rendering policy Default Markdown output should optimize for human reading. Rules: - Start with `# {title}`. - Use stable `HH:MM:SS` timestamps with seconds precision. - Use an en dash between start and end timestamps. - Omit segment IDs by default. - Omit metadata by default. - Render speaker names in bold. - Render segment text as normal prose unless category hints apply. - Do not expose internal category names by default. - Do not expose unknown categories by default. - Do not fail on unknown categories. - Omit overlap/debug metadata by default. Category hints: - `background` text should be italicized. - `backchannel` text may be italicized. - `filler` text may be italicized. - Unknown categories should be ignored. Example default shape: # Transcript [00:00:01-00:00:04] **Eric Rakestraw:** Hello there. [00:00:05-00:00:08] **Mike Brown:** Welcome back, everyone. [00:00:09-00:00:10] **Eric Rakestraw:** *Yeah.* The roadmap uses an ASCII hyphen in the example for source compatibility. Implementation should use an en dash in the rendered Markdown output. ## Internal architecture Add a new `internal/render` package for render-specific behavior. Responsibilities: - read or accept parsed seriatim artifacts through a neutral artifact helper; - normalize full/intermediate/minimal artifacts into a render model; - expose a renderer registry keyed by public format names; - provide the initial `markdown` renderer; - keep renderer code free of CLI, filesystem path, environment variable, and report concerns. Artifact parsing: - Do not import `internal/trim` only to parse render input. - Move or generalize artifact parsing into a neutral artifact helper that both `trim` and `render` can use. - Keep schema validation through `schema`. Command boundary: - CLI code should parse flags, construct validated config, and delegate. - Config validation should live in `internal/config`. - Filesystem read/write orchestration should live in `internal/render` or a narrow artifact/render run layer, following the `trim` and `normalize` artifact-level command pattern. - Use existing JSON/text file writing conventions where practical. Report support: - Do not add `--report-file` in the initial implementation. - Rendering is presentation output rather than semantic transformation, so reports are lower priority. ## Validation and error handling Validation should fail fast with contextual errors: - missing `--input-file`, `--output-file`, or `--format`; - input path does not exist or is a directory; - output parent directory does not exist; - malformed JSON; - JSON that does not validate as a seriatim minimal/intermediate/full artifact; - unsupported `--format`; - output file write failure. Important behavior: - Raw WhisperX-style JSON must fail because it is not a seriatim output artifact. - Unknown segment categories must not fail rendering. - Empty transcripts should render deterministically. - Negative or inverted timing should fail through existing schema validation. - Commands should return errors to the root command; internal packages should not print. ## Testing strategy Add tests at the package level that owns each behavior: - artifact parsing/normalization tests for all three public schemas; - rejection tests for malformed JSON and raw WhisperX-like input; - registry tests for resolving `markdown` and rejecting unknown formats; - Markdown renderer tests for title, timestamps, speaker bolding, italicized category hints, unknown category handling, metadata flags, and segment ID flags; - config tests for required flags, path validation, and format validation; - CLI tests for command registration, end-to-end Markdown output, and error behavior; - full repository test after integration. Required validation commands after implementation: go test ./internal/render ./internal/config ./internal/cli ./schema go test ./... go run ./cmd/seriatim --help go run ./cmd/seriatim render --help ## Documentation updates required Do not update current-behavior docs until the command is implemented. After implementation, update: - `README.md`: add `render` to the concise command summary if useful. - `docs/cli.md`: add render command reference and workflow. - `docs/config.md`: document render flags only if they belong in config reference. - `docs/operations.md`: add render to the file workflow. - `docs/internal/artifacts.md`: describe artifact parsing/render model internals. - `examples/`: add a small synthetic Markdown render example if practical. ## Open decisions No blocking decisions remain for the initial roadmap. Defaults chosen for the first implementation: - initial format: `markdown`; - initial title: `Transcript`; - timestamps included by default; - segment IDs omitted by default; - metadata omitted by default; - no initial render reports; - no initial templates; - no initial paragraph or speaker-turn coalescing. ## Staged implementation plan ### Stage 1: artifact reader and render model Objective: - Add neutral artifact parsing and normalization support for render input. Likely packages: - `internal/artifact` - `internal/render` - `schema` - `internal/trim`, only if shared parsing moves out of trim Implementation details: - Move or generalize current trim artifact parsing into a neutral artifact helper that accepts minimal, intermediate, and full seriatim artifacts. - Keep validation through `schema`. - Add a render model with normalized segment fields: ID, start, end, speaker, text, categories. - Preserve source artifact order and existing segment IDs. - Do not add Markdown rendering in this stage. Tests: - Parse and normalize full, intermediate, and minimal artifacts. - Reject malformed JSON. - Reject raw WhisperX-like JSON. - Preserve categories where present and use empty categories where absent. Acceptance criteria: - Render model can be produced from all current seriatim output schemas. - Raw input formats are not accepted. - Trim remains behavior-compatible if artifact parsing is shared. ### Stage 2: renderer registry and Markdown renderer Objective: - Add renderer resolution and initial deterministic Markdown rendering. Likely packages: - `internal/render` Implementation details: - Add renderer interface and registry keyed by public format name. - Register `markdown`. - Add Markdown options for title, timestamps, segment IDs, and metadata. - Format timestamps as `HH:MM:SS` with seconds precision. - Italicize text for `background`, `backchannel`, and `filler`. - Ignore unknown categories. - Keep renderer independent of CLI/config/filesystem. Tests: - Resolve `markdown`. - Reject unknown renderer names. - Render default transcript shape. - Render without timestamps. - Render with segment IDs. - Render metadata only when requested. - Render category hint italics. - Ignore unknown categories without error. Acceptance criteria: - Markdown output is deterministic and human-readable. - Renderer package has no Cobra, config, environment, or filesystem-path dependency. ### Stage 3: render command configuration and CLI wiring Objective: - Add `seriatim render` as a top-level command. Likely packages: - `internal/config` - `internal/cli` - `internal/render` Implementation details: - Add `RenderOptions` and `RenderConfig`. - Validate required input, output, and format flags. - Reuse existing single-input and output-path validation helpers. - Add `newRenderCommand`. - Register render in root command. - Add flags: `--input-file`, `--output-file`, `--format`, `--title`, `--include-timestamps`, `--include-segment-ids`, `--include-metadata`. - Add `render.Run(ctx, cfg)` for artifact-level orchestration. Tests: - Config required flag validation. - Config format validation. - CLI command is recognized. - CLI end-to-end Markdown render from a small artifact. - Root help includes `render`. Acceptance criteria: - `seriatim render --input-file transcript.json --output-file transcript.md --format markdown` works. - CLI code remains thin and delegates to config/render packages. ### Stage 4: validation, errors, and schema coverage Objective: - Harden user-facing failure behavior and all schema variants. Likely packages: - `internal/render` - `internal/config` - `internal/cli` Implementation details: - Wrap input read, artifact parse, unsupported format, and output write errors with useful context. - Verify raw WhisperX-style input fails with an artifact validation error. - Verify empty transcripts render deterministically. - Verify output parent directory validation matches other commands. Tests: - Unsupported `--format`. - Missing or directory input file. - Malformed JSON. - Raw WhisperX-like JSON. - Output parent missing. - Minimal, intermediate, and full schema CLI coverage. Acceptance criteria: - Error behavior matches repository conventions. - All supported JSON artifact schemas are covered by tests. ### Stage 5: documentation updates after implementation Objective: - Update current-behavior docs only after render exists. Likely files: - `README.md` - `docs/cli.md` - `docs/config.md` - `docs/operations.md` - `docs/internal/artifacts.md` - `examples/README.md` Implementation details: - Add concise user-facing render docs. - Keep full flag reference in `docs/cli.md`. - Keep config docs limited to actual render flags and path validation. - Add a small synthetic render example if practical. - Do not describe future render formats as implemented. Tests: - Run example command if an example is added. - Run full Go tests after doc/example changes. Acceptance criteria: - Non-roadmap docs describe only implemented render behavior. - README remains concise. ### Stage 6: final integration hardening Objective: - Verify the feature is complete, deterministic, and aligned with architecture. Likely packages: - `cmd/seriatim` - `internal/cli` - `internal/config` - `internal/render` - `internal/artifact` - `schema` Implementation details: - Run full tests and CLI help checks. - Review package imports for boundary drift. - Confirm no merge modules are invoked by render. - Confirm no report flag slipped into v1. - Confirm future formats can register without renaming the command. Tests: - `go test ./...` - `go run ./cmd/seriatim --help` - `go run ./cmd/seriatim render --help` Acceptance criteria: - All tests pass. - Render remains artifact-level and downstream-only. - Markdown output is reproducible from JSON input and render flags.