Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b1eb37d80d |
@@ -1,446 +0,0 @@
|
|||||||
# 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.
|
|
||||||
Reference in New Issue
Block a user