# Artifact Internals ## Purpose Describes implemented artifact parsing, conversion, validation, and render-model normalization internals. ## Artifact contracts Public contracts live in `schema/`: - full: `schema.Transcript` - intermediate: `schema.IntermediateTranscript` - minimal: `schema.MinimalTranscript` Machine-readable schemas: - `schema/full-output.schema.json` - `schema/intermediate-output.schema.json` - `schema/minimal-output.schema.json` ## Shared output-artifact parser `internal/artifact/output_artifact.go` provides schema-aware parsing for existing seriatim output artifacts. Behavior: - accepts only valid full, intermediate, or minimal seriatim output artifacts - validates through `schema` semantic + JSON schema checks - rejects malformed JSON - rejects raw WhisperX-style JSON and other non-seriatim shapes Consumers: - `internal/trim` artifact-level trim flow - `internal/render` artifact-level render flow ## Merge conversion behavior `internal/artifact/transcript.go` converts `model.MergedTranscript` to public contracts: - full schema preserves source/provenance, overlap groups, and metadata module lists - intermediate schema emits segment timing/text/speaker with optional categories and compact metadata - minimal schema emits compact segment timing/text/speaker and compact metadata Schema selection uses `internal/artifact.SelectedFromMerged`: - `seriatim-full` -> `artifact.FromMerged` - `seriatim-intermediate` -> `artifact.IntermediateFromMerged` - `seriatim-minimal` -> `artifact.MinimalFromMerged` - unknown/empty -> intermediate fallback ## Trim internals `internal/trim` handles artifact-level projection and does not execute merge pipeline modules. Run layer (`run.go`): 1. Parse selector from validated config. 2. Read and parse input artifact JSON. 3. Apply trim projection through schema-aware artifact handling. 4. Resolve output schema (preserve input schema unless overridden). 5. Validate output artifact. 6. Write output JSON. 7. Optionally write report JSON with `trim-audit`. Apply layer (`apply.go`): - one shared projection policy for selector mode, input ID validation, selected ID existence checks, keep/remove filtering, removed IDs, and old-to-new ID mappings - schema-specific segment reconstruction for full/intermediate/minimal outputs - overlap-group recomputation only for full-schema outputs Artifact conversion layer (`artifact.go`): - schema-preserving trim application - supported schema conversions: - full -> intermediate/minimal - intermediate -> minimal - minimal -> intermediate - rejected conversion: - intermediate/minimal -> full Trim invariants: - selected IDs must exist in input - input IDs must be positive, unique, sequential - retained segment order follows input transcript order - output IDs are reassigned to `1..N` ## Normalize internals `internal/normalize` canonicalizes transcript-like JSON input into a selected public schema. Parse layer (`parse.go`): - accepts object-with-`segments` or bare segment array - repairs missing timing deterministically - swaps inverted timing - fills missing/blank speaker with `Unknown_Speaker` - drops missing/blank text segments Build layer (`build.go`): - sorts deterministically by `(start, end, input_index, speaker)` - reassigns output IDs sequentially - builds minimal/intermediate/full output shape - validates selected output schema before write Run layer (`normalize.go`): - writes output JSON - optionally writes report with `normalize-audit` Normalize invariant: - report events do not embed transcript text ## Render internals `internal/render` is an artifact-level, downstream-only renderer. Model normalization (`normalize.go`): - converts full/intermediate/minimal artifacts into a common render model - preserves segment order and segment IDs - normalizes per-segment fields to ID, start, end, speaker, text, categories - emits empty categories slice when categories are absent in input Renderer registry (`registry.go`): - resolves renderers by public format name - currently registers `markdown` Markdown renderer (`markdown.go`): - writes title header `# {title}` - renders optional `[HH:MM:SS–HH:MM:SS]` timestamps - renders optional `[#id]` segment references - renders `**speaker:** text` - italicizes text when categories include `background`, `backchannel`, or `filler` - ignores unknown categories - optionally includes metadata summary block Run layer (`run.go`): 1. Read input artifact JSON. 2. Parse via shared output-artifact parser. 3. Normalize to render model. 4. Resolve renderer by `--format`. 5. Render text output. 6. Write output file. Render invariants: - does not run merge/trim/normalize modules - does not expose report output - deterministic for identical input artifact and render flags ## Validation behavior `schema/output.go` validates both structure and semantics: - embedded JSON Schema validation via `jsonschema/v6` - semantic checks for sequential segment IDs starting at `1` - semantic checks for non-inverted segment timing (`end >= start`) - full schema overlap-group timing checks (`group.end >= group.start`) ## Boundaries - CLI flag semantics belong to `docs/cli.md`. - Runtime config/env surfaces belong to `docs/config.md`. - This document describes internal conversion/validation behavior only. ## Failure behavior Representative failure classes: - malformed or unsupported input JSON shape - schema validation failure for parsed artifact or built output - unsupported schema conversion path (trim) - selector or input-ID consistency errors (trim) - unsupported renderer format (render) - output/report file write failures from command paths ## Tests to inspect before changes - `schema/output_test.go` - `internal/artifact/transcript_test.go` - `internal/artifact/output_artifact_test.go` - `internal/trim/selector_test.go` - `internal/trim/artifact_test.go` - `internal/trim/apply_test.go` - `internal/normalize/parse_test.go` - `internal/render/normalize_test.go` - `internal/render/markdown_test.go` - `internal/render/registry_test.go` - `internal/cli/trim_test.go` - `internal/cli/normalize_test.go` - `internal/cli/render_test.go` ## Invariants - Public artifacts are validated through `schema` before acceptance. - Segment IDs in emitted artifacts are sequential and deterministic. - Internal-only fields are not emitted in minimal/intermediate contracts. - Trim, normalize, and render stay artifact-level and do not execute merge modules.