221 lines
10 KiB
Markdown
221 lines
10 KiB
Markdown
# Architecture Policy
|
|
|
|
## Purpose
|
|
|
|
This document defines seriatim's development architecture and invariants for
|
|
maintainers and automated coding agents. It describes how the implemented
|
|
system is intended to be built and changed. It is not a user manual, CLI
|
|
reference, config reference, or roadmap.
|
|
|
|
Keep this document aligned with [documentation policy](documentation.md). It
|
|
must describe current behavior only; planned or speculative work belongs under
|
|
`docs/roadmap/`.
|
|
|
|
## Project Shape
|
|
|
|
seriatim is a Go CLI for transcript artifact processing. The implemented
|
|
commands are `merge`, `trim`, `normalize`, and `render`.
|
|
|
|
`merge` reads one or more JSON transcript files, optionally maps input files to
|
|
canonical speakers, runs a registry-selected preprocessing chain, merges
|
|
canonical segments into deterministic chronological order, runs a
|
|
registry-selected postprocessing chain, validates the selected output schema,
|
|
and writes JSON output plus an optional JSON report.
|
|
|
|
`trim`, `normalize`, and `render` are artifact-level commands outside the merge
|
|
pipeline. `trim` reads an existing seriatim output artifact and projects it by
|
|
segment ID. `normalize` reads transcript-like JSON and emits one of seriatim's
|
|
supported output schemas. `render` reads an existing seriatim output artifact
|
|
and emits human-readable Markdown. None of these commands runs merge
|
|
preprocessing or postprocessing modules.
|
|
|
|
The supported public output schemas are `seriatim-minimal`,
|
|
`seriatim-intermediate`, and `seriatim-full`. For command and flag details, use
|
|
[CLI reference](../cli.md) and [configuration reference](../config.md).
|
|
|
|
## Core Design Principles
|
|
|
|
- Keep a hexagonal architecture boundary. Domain models, stage contracts, and
|
|
deterministic transformations must stay separate from CLI parsing,
|
|
filesystem access, config loading, reporting, and other external adapters.
|
|
- Keep stages and modules composable. Built-in modules are selected by
|
|
canonical registry names and implement explicit interfaces for their pipeline
|
|
role.
|
|
- Preserve deterministic behavior. Given the same inputs, configuration, and
|
|
version, output ordering, segment IDs, schema validation, and report event
|
|
ordering should remain stable.
|
|
- Current command execution is sequential. There is no scheduler, worker pool,
|
|
or concurrent module execution in the implemented pipeline. Any concurrency
|
|
added later must be bounded, observable, and must not make output handling
|
|
nondeterministic.
|
|
- Prefer the Go standard library. Third-party dependencies should remain narrow
|
|
and justified, such as Cobra for CLI structure, YAML parsing, and JSON Schema
|
|
validation.
|
|
- Document current behavior. Architecture, user, and internal docs must not
|
|
describe planned features as implemented behavior.
|
|
|
|
## Architectural Boundaries
|
|
|
|
Core transcript data belongs in `internal/model` and public artifact contracts
|
|
belong in `schema`. Conversion from internal merged data to public JSON shapes
|
|
belongs at the artifact boundary, not inside CLI code or transformation
|
|
packages.
|
|
|
|
Pipeline orchestration belongs in `internal/pipeline`. It resolves registered
|
|
modules, validates preprocessing state transitions, executes stages in order,
|
|
collects report events, converts the final transcript, and writes optional
|
|
reports. Built-in adapters and modules are registered from `internal/builtin`.
|
|
|
|
CLI code in `internal/cli` should parse flags, build validated config values,
|
|
and delegate. `merge` delegates to `pipeline.Run`; `trim`, `normalize`, and
|
|
`render` perform artifact-level orchestration and delegate deterministic
|
|
parsing, validation, and transformation work to their internal packages.
|
|
|
|
Config loading and validation belongs in `internal/config`. Filesystem reads and
|
|
writes are adapter concerns and should not spread into pure transformation
|
|
helpers. Existing built-in modules that load configured YAML files must keep
|
|
that I/O narrow and explicit.
|
|
|
|
Reports belong in `internal/report`. Modules and commands should emit concise
|
|
events for validation findings, corrections, and transformations without
|
|
turning report messages into a duplicate output artifact.
|
|
|
|
Tests and samples are supporting evidence for behavior. Tests should verify
|
|
stable contracts and edge cases; samples should remain valid examples, not
|
|
hidden architecture dependencies.
|
|
|
|
## Modules or Stages
|
|
|
|
The merge pipeline has these implemented stages:
|
|
|
|
- `InputReader`: reads configured external input into raw transcripts.
|
|
- `Preprocessor`: transforms `PreprocessState` from raw to canonical state.
|
|
- `Merger`: combines canonical transcripts into one merged transcript.
|
|
- `Postprocessor`: transforms or annotates the merged transcript.
|
|
- `OutputWriter`: writes the selected output artifact.
|
|
|
|
Modules must keep narrow responsibilities, declare their stage through the
|
|
interface they implement, and use explicit config values. Preprocessors must
|
|
declare `Requires()` and `Produces()` states; the runner rejects invalid
|
|
raw/canonical ordering before processing completes.
|
|
|
|
Modules run in the configured order. Order-affecting modules must run before
|
|
`assign-ids`, and `validate-output` must see final IDs that match the selected
|
|
schema. Accepted and rejected transformations should be deterministic and, when
|
|
observable, recorded through report events.
|
|
|
|
Transformation helpers should avoid hidden global state. Shared caches, such as
|
|
compiled JSON schemas, must be protected and must not affect output ordering.
|
|
|
|
## State, Inputs, and Outputs
|
|
|
|
seriatim is file-based. It reads JSON inputs and optional YAML rule files, then
|
|
writes JSON transcript artifacts and optional JSON reports.
|
|
|
|
The implemented application has no durable database, daemon state, resume
|
|
state, remote storage, or background job state. Runtime state is held in memory
|
|
for the current command invocation and serialized only through requested output
|
|
and report files.
|
|
|
|
Input file paths are normalized and validated during config construction.
|
|
`merge` sorts input file paths before processing, then uses stable segment sort
|
|
keys. `trim` preserves transcript order while renumbering retained IDs.
|
|
`normalize` sorts by implemented deterministic keys and assigns fresh IDs.
|
|
|
|
## Configuration and CLI Boundaries
|
|
|
|
The CLI surface is an adapter over validated config structs. Cobra command code
|
|
should stay thin: parse flags, account for flag/default precedence, call config
|
|
constructors, and delegate.
|
|
|
|
Config constructors validate required paths, output parent directories, module
|
|
lists, selected schemas, mutually exclusive trim selector options, and supported
|
|
environment-derived settings. Module name validation is split between config
|
|
where command-specific names are fixed and the pipeline registry where module
|
|
composition is resolved.
|
|
|
|
Do not duplicate full CLI or config reference material here. Use
|
|
[CLI reference](../cli.md) and [configuration reference](../config.md) for
|
|
canonical user-facing details.
|
|
|
|
## Errors, Logging, and Diagnostics
|
|
|
|
Commands return errors instead of printing inside deep logic. The root command
|
|
silences Cobra usage/error output, and `cmd/seriatim/main.go` prints one error
|
|
to stderr and exits with status `1`.
|
|
|
|
Validation failures should fail fast with contextual errors. Correctable
|
|
conditions should be deterministic and, where reports are requested, reflected
|
|
as report events. Optional reports contain metadata and ordered events; they are
|
|
not required for command success unless the report file itself cannot be
|
|
written.
|
|
|
|
The implemented code does not use a logging subsystem. Diagnostics are returned
|
|
as errors or written to optional report JSON. Normalize report events avoid
|
|
embedding transcript text; keep that privacy-oriented behavior when changing
|
|
normalize diagnostics.
|
|
|
|
## Testing Expectations
|
|
|
|
`go test ./...` is the repository-wide check. There is currently no Makefile,
|
|
taskfile, linter config, or dedicated documentation check.
|
|
|
|
When changing config or CLI behavior, inspect `internal/config` and
|
|
`internal/cli` tests. When changing pipeline composition or stage contracts,
|
|
inspect `internal/pipeline` and `internal/builtin` tests. When changing
|
|
correction or annotation modules, inspect the package tests for overlap,
|
|
coalesce, danglers, backchannel, filler, and autocorrect behavior.
|
|
|
|
When changing artifact-level commands, inspect `internal/trim`,
|
|
`internal/normalize`, `internal/render`, and their CLI tests. When changing
|
|
public output shape or schema validation, inspect `schema` and
|
|
`internal/artifact` tests. Report and diagnostic changes should be covered
|
|
through the command or package tests that emit the affected events.
|
|
|
|
## Dependency Policy
|
|
|
|
Prefer the Go standard library for parsing, data transformation, concurrency
|
|
primitives, filesystem work, and testing wherever it is reasonable.
|
|
|
|
Third-party dependencies must be narrow, justified, and preferably de facto
|
|
standard for their purpose. Existing examples include Cobra for CLI structure,
|
|
`gopkg.in/yaml.v3` for YAML files, and `jsonschema/v6` for validating embedded
|
|
public JSON schemas. Avoid broad framework dependencies for behavior that is
|
|
already simple and local.
|
|
|
|
## Documentation Expectations
|
|
|
|
Architecture docs must stay aligned with [documentation policy](documentation.md).
|
|
Current-behavior docs must not become aspirational. If code and docs disagree,
|
|
fix the inaccurate current-behavior doc or put planned work under
|
|
`docs/roadmap/`.
|
|
|
|
Prefer links to canonical docs instead of repeating full CLI, config, schema, or
|
|
operations reference material. Keep examples real, tested where practical, and
|
|
free of secrets or private transcript data.
|
|
|
|
## Architectural Invariants
|
|
|
|
- Keep core/domain logic separate from CLI, config, filesystem, reporting, and
|
|
other adapter concerns.
|
|
- Centralize default configuration values as constants defined in internal/config/config.go.
|
|
- Keep modules narrowly scoped, explicitly configured, and composable by
|
|
registry name.
|
|
- Preserve deterministic ordering, final segment ID assignment, and schema
|
|
validation before output acceptance.
|
|
- Keep `trim`, `normalize`, and `render` artifact-level; do not run merge
|
|
modules from those commands.
|
|
- Keep public output schemas validated through `schema`.
|
|
- Keep optional reports ordered, concise, and diagnostic.
|
|
- Avoid broad dependencies without a concrete maintainability benefit.
|
|
- Do not document unimplemented behavior outside `docs/roadmap/`.
|
|
|
|
## Non-Goals
|
|
|
|
The implemented application does not perform transcription, audio diarization,
|
|
speaker inference from audio or text, summarization, daemon operation, remote
|
|
storage, dynamic external plugin loading, or concurrent pipeline execution.
|
|
|
|
The architecture policy is not a package-by-package reference, CLI manual,
|
|
config reference, schema reference, or roadmap.
|