voxi developer docs.
voxi is a small, spec-driven Go codebase: configuration and model behavior live in version-controlled YAML, not scattered constants, and the accuracy work behind its ASR defaults is backed by real recorded-speech fixtures rather than guesswork. This page covers the parts of voxi that matter to contributors, not to everyday dictation — for that, see the main voxi page.
Spec-Driven Architecture
Spec files are the single source of truth — application code must not duplicate or shadow spec values. Every YAML file is embedded directly into the binary and validated against a companion JSON Schema.
spec/
├── actions.yaml # voxi monitor hotkeys & display labels
├── models.yaml # ASR model registry & hallucination filters
├── monitor.yaml # redraw rate & live mic-level ballistics
└── schemas
├── actions.schema.json
├── models.schema.json
└── monitor.schema.json
spec/models.yaml names every ASR model voxi can drive and its per-model
hallucination stop-words. spec/actions.yaml is the single source for
voxi monitor's hotkeys — box titles and footer badges resolve their
key letters from it, so they can never drift out of sync with the actual dispatcher.
spec/monitor.yaml tunes the live mic-loudness meter (paint FPS, capture
rate, attack/decay ballistics) without touching Go code. Run make validate-spec
to check every spec file against its JSON Schema before committing.
Contributing & Workflow
voxi is a solo/hobby project on a single default branch (main), with no
PR-triage web workflow — proposals, bugs, and architectural changes are tracked
as Markdown files under issues/ in the repository itself.
| Area | Convention |
|---|---|
| Commits | Conventional Commits (feat, fix, docs, refactor, test, chore) |
| Issues & proposals | Markdown files under issues/ (e.g. issues/NNN-topic-name.md), submitted via merge requests |
| Go style | Standard library first; external deps need explicit rationale. Allowed: spf13/cobra, gopkg.in/yaml.v3 |
| Errors & state | No panic() outside startup; wrap errors with fmt.Errorf("context: %w", err); no package-level mutable state |
| Tests | Standard library testing, table-driven, deterministic and hermetic |
$ make help # Show available make targets
$ make test # go vet + go test across all packages
$ make validate-spec # Validate spec/*.yaml against embedded JSON schemas
$ make check # Full test suite + spec validations
$ make install # Install voxi (binary, deps, services, man page) to ~/go/bin
$ make man # Generate roff man page to voxi.1
$ make website-manual # Regenerate website/man/ from the live Cobra tree
Dev Samples & Accuracy Canaries
Samples are saved audio for accuracy checks, no-speech checks, and voice cloning. Chunks are temporary recordings cut by live dictation, kept with diagnostics; use them directly or save them as samples. This is a private, contributor-only capability — it plays no part in everyday dictation.
$ voxi sample record <id> # Record one utterance + corrected transcript
$ voxi sample add <id> --last # Keep the last dictation chunk as a sample
$ voxi sample list # List samples by purpose
$ voxi sample play <id> # Replay a sample
$ voxi sample merge <id> <a> <b> # Join samples; 20s default limit
$ voxi sample publish <id> # Publish a noise-only sample to the repository
Each sample pairs a recording with metadata and one purpose: dictation (ASR accuracy
checks), noise (must yield no text) or voice (your own voice for cloning and
training, with explicit own-voice consent required when adding or moving it into that purpose).
Samples are stored
privately under ~/.local/share/voxi/samples/, since they hold real recorded
speech. Only a noise sample confirmed to contain no intelligible speech (keyboard clacks,
mouse or ambient noise) can be published into testdata/samples/noise/, the
repository's public, git-tracked store used for noise-vs-speech fixtures. A
chunk is different: one recording cut by live dictation; only the last 100 are kept.