Add render command roadmap

This commit is contained in:
2026-05-24 17:07:47 -05:00
parent 9202ccddb9
commit a90859114a

446
docs/roadmap/render.md Normal file
View File

@@ -0,0 +1,446 @@
# 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.