|
| 1 | +# sotto Agent Guide |
| 2 | + |
| 3 | +## Scope |
| 4 | + |
| 5 | +These rules apply to the entire `sotto/` repository. |
| 6 | + |
| 7 | +## Mission |
| 8 | + |
| 9 | +Ship a production-grade, local-first ASR CLI with: |
| 10 | + |
| 11 | +- a single Go binary |
| 12 | +- no background daemon |
| 13 | +- strong crash/cleanup guarantees |
| 14 | +- clear modular boundaries for safe refactoring |
| 15 | +- reproducible packaging and CI |
| 16 | + |
| 17 | +## First 60 Seconds (Progressive Disclosure) |
| 18 | + |
| 19 | +1. Read this file fully. |
| 20 | +2. Read `README.md` for user-facing behavior. |
| 21 | +3. Read `PLAN.md` (current milestones/checklist) and `SESSION.md` (what actually ran). |
| 22 | +4. Run `just --list` to see current task entrypoints. |
| 23 | +5. Open only the component(s) you are changing (map below). |
| 24 | + |
| 25 | +--- |
| 26 | + |
| 27 | +## Project Map (What to read by task) |
| 28 | + |
| 29 | +| Area | Primary paths | Notes | |
| 30 | +| --- | --- | --- | |
| 31 | +| CLI contract + dispatch | `apps/sotto/internal/cli/`, `apps/sotto/internal/app/` | Commands, flags, top-level flow | |
| 32 | +| Session state machine | `apps/sotto/internal/session/`, `apps/sotto/internal/fsm/`, `apps/sotto/internal/ipc/` | Toggle/stop/cancel semantics, single-instance behavior | |
| 33 | +| Audio capture + device selection | `apps/sotto/internal/audio/` | PipeWire/Pulse capture, device fallback/mute handling | |
| 34 | +| Riva streaming ASR | `apps/sotto/internal/riva/`, `apps/sotto/internal/pipeline/` | gRPC stream config, segment assembly inputs | |
| 35 | +| Transcript assembly | `apps/sotto/internal/transcript/` | Whitespace normalization + trailing-space behavior | |
| 36 | +| Output dispatch | `apps/sotto/internal/output/`, `apps/sotto/internal/hypr/` | Clipboard + paste behavior | |
| 37 | +| Indicator + cues | `apps/sotto/internal/indicator/` | Visual notify + audio cue lifecycle | |
| 38 | +| Config grammar/defaults | `apps/sotto/internal/config/` | Any new key must update parser/defaults/tests/docs | |
| 39 | +| Packaging + tooling | `justfile`, `flake.nix`, `.github/workflows/` | CI/tooling changes | |
| 40 | +| Protobuf contracts | `apps/sotto/proto/third_party/`, `proto/gen/go/` | Run codegen when proto inputs change | |
| 41 | + |
| 42 | +--- |
| 43 | + |
| 44 | +## Engineering Workflow Rules |
| 45 | + |
| 46 | +1. Read target files before editing. |
| 47 | +2. Keep changes aligned to `PLAN.md` milestones; avoid drive-by refactors. |
| 48 | +3. Keep `PLAN.md` checkboxes accurate (only mark executed + verified work). |
| 49 | +4. Log key decisions/trade-offs/blockers/commands in `SESSION.md`. |
| 50 | +5. Prefer additive changes with regression tests. |
| 51 | +6. Never claim runtime integrations (Riva, PipeWire, Hyprland) were verified unless actually exercised. |
| 52 | + |
| 53 | +### Design principles (repo-wide) |
| 54 | + |
| 55 | +- Prefer boring, explicit code over clever code. |
| 56 | +- Fail fast at boundaries (config parse, startup checks, I/O preconditions). |
| 57 | +- Keep business/state logic separate from transport/I/O adapters. |
| 58 | +- Use guard clauses to reduce nesting. |
| 59 | +- Keep files top-down readable (public entrypoints first, private helpers below). |
| 60 | + |
| 61 | +### Dependency + architecture rules |
| 62 | + |
| 63 | +- Prefer manual constructor-based dependency injection. |
| 64 | +- Keep package responsibilities narrow; avoid utility dumping grounds. |
| 65 | +- Do not couple domain/state transitions directly to shell command details. |
| 66 | + |
| 67 | +--- |
| 68 | + |
| 69 | +## Go Conventions |
| 70 | + |
| 71 | +- Use table-driven tests for branch-heavy logic. |
| 72 | +- Prefer `errors.Is` / wrapped errors with context. |
| 73 | +- Keep I/O timeouts explicit. |
| 74 | +- Use `testing` + `testify` (`require`/`assert`) for expressive assertions when useful. |
| 75 | +- Add focused regression tests for bug fixes whenever feasible. |
| 76 | + |
| 77 | +### Testing boundaries (repo policy) |
| 78 | + |
| 79 | +- Prefer real interfaces/adapters and real resources (temp files, unix sockets, `httptest`, PATH fixtures). |
| 80 | +- Do **not** introduce mocking frameworks or expectation-driven mock suites. |
| 81 | +- Riva runtime/model inference remains a local-manual smoke concern (non-CI); use lightweight protocol/contract tests in CI. |
| 82 | + |
| 83 | +### File size / readability guardrails |
| 84 | + |
| 85 | +- Handwritten files should target `<= 250` LOC where practical. |
| 86 | +- Files above `~350` LOC require extraction-plan notes in `PLAN.md` before refactor work. |
| 87 | +- Exclude generated code from these thresholds: `apps/sotto/vendor/**`, `apps/sotto/proto/gen/**`. |
| 88 | + |
| 89 | +--- |
| 90 | + |
| 91 | +## Config Change Contract (Mandatory) |
| 92 | + |
| 93 | +When adding or changing a config key, update all of: |
| 94 | + |
| 95 | +1. `apps/sotto/internal/config/types.go` |
| 96 | +2. `apps/sotto/internal/config/defaults.go` |
| 97 | +3. `apps/sotto/internal/config/parser.go` |
| 98 | +4. validation if required (`validate.go`) |
| 99 | +5. parser/validation tests |
| 100 | +6. `README.md` config example + notes |
| 101 | +7. any deployed default config in consuming repos (when in scope) |
| 102 | + |
| 103 | +--- |
| 104 | + |
| 105 | +## Required Local Checks Before Hand-off |
| 106 | + |
| 107 | +Run and report status for: |
| 108 | + |
| 109 | +1. `just ci-check` |
| 110 | +2. `nix build 'path:.#sotto'` |
| 111 | + |
| 112 | +If any check is skipped, state exactly what was skipped, why, and the exact command to run. |
| 113 | + |
| 114 | +### Pre-commit Hooks (`prek`) |
| 115 | + |
| 116 | +- Install hooks: `just precommit-install` |
| 117 | +- Run hooks manually: `just precommit-run` |
| 118 | + |
| 119 | +Use hooks to catch formatting/lint drift before pushing. |
| 120 | + |
| 121 | +--- |
| 122 | + |
| 123 | +## Safety |
| 124 | + |
| 125 | +- Never store secrets in repo files. |
| 126 | +- Assume `NGC_API_KEY` and other credentials are external env/secrets only. |
| 127 | +- Avoid destructive shell operations unless explicitly requested. |
| 128 | +- Do not edit files outside `sotto/` unless explicitly requested. |
0 commit comments