scaffold: M0 skeleton + agent onboarding (build, architecture, progress)
Turn the design into a buildable, dependency-free M0 skeleton plus the
onboarding layer so a new agent can pick up instantly.
Build system:
- CMake + CMakePresets (dev = no deps; server-release = vcpkg) + vcpkg.json
- Skeleton builds with just a C++20 compiler; deps stay off until needed
- .gitattributes (LF), .gitignore, .clang-format
Core (libvoicecat):
- core/include/voicecat.h: full C ABI (the client/server contract), stubbed
- core/proto/voicecat.proto: control-plane wire format, matches docs/protocol.md
- src/{net,crypto,codec,protocol,session,audio,core}: subsystem stubs that
return VC_ERR_NOT_IMPLEMENTED, each pointing to its design doc
- server/ (voicecat-server) and tools/vccli/ link the core
- tests/: CTest smoke test asserting the C ABI contract (behavior, not just build)
- clients/{apple,windows}: M4 placeholders
Onboarding for agents:
- CLAUDE.md: hub — build/test commands, architecture at a glance, doc map, rules
- AGENTS.md: working method (behavior-driven; clean compile is the floor not the goal)
- PROGRESS.md: living tracker — M0 done, M1 task checklist, "where we left off"
Verified: cmake --preset dev && cmake --build --preset dev && ctest --preset dev → green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
141
CLAUDE.md
Normal file
141
CLAUDE.md
Normal file
@@ -0,0 +1,141 @@
|
||||
# CLAUDE.md — agent hub for VoiceCat
|
||||
|
||||
Auto-loaded each session. This is the **map**: build commands, architecture at a glance, and
|
||||
where everything is. For the *working method* read [`AGENTS.md`](AGENTS.md); for *what's done
|
||||
and what's next* read [`PROGRESS.md`](PROGRESS.md); for *design* read [`docs/`](docs/).
|
||||
|
||||
> **One-line status:** M0 skeleton is complete and verified (builds + links + smoke test
|
||||
> passes). Next up is **M1** (TCP/TLS control plane, auth, channels, ephemeral text). See
|
||||
> [`PROGRESS.md`](PROGRESS.md).
|
||||
|
||||
VoiceCat = self-hosted native voice & text chat (TeamSpeak/Mumble-style). Plain TCP (control)
|
||||
+ UDP (media), no WebRTC, encrypted by default. A shared C++ core (`libvoicecat`) drives
|
||||
native clients (Swift on macOS/iOS, C# on Windows) and the server.
|
||||
|
||||
---
|
||||
|
||||
## Build & test commands
|
||||
|
||||
The **M0 skeleton builds with no third-party dependencies** — just CMake + Ninja + a C++20
|
||||
compiler. Deps (vcpkg) are off until a subsystem needs them.
|
||||
|
||||
```bash
|
||||
# Configure + build the skeleton (default; no vcpkg needed)
|
||||
cmake --preset dev
|
||||
cmake --build --preset dev
|
||||
|
||||
# Run the tests (behavior smoke test today; grows per milestone)
|
||||
ctest --preset dev # or: ctest --test-dir build/dev --output-on-failure
|
||||
|
||||
# Run the binaries (Windows adds .exe; Linux/macOS no extension)
|
||||
./build/dev/bin/vccli # headless test client
|
||||
./build/dev/bin/voicecat-server --help
|
||||
./build/dev/bin/voicecat-server --name "My Server"
|
||||
|
||||
# Build a single target / be verbose
|
||||
cmake --build --preset dev --target vccli
|
||||
cmake --build --preset dev --verbose
|
||||
|
||||
# Clean
|
||||
rm -rf build/dev # nuke; or:
|
||||
cmake --build --preset dev --target clean
|
||||
```
|
||||
|
||||
When you start a subsystem that needs real libraries (mbedTLS, libsodium, opus, protobuf, …),
|
||||
turn vcpkg deps on:
|
||||
|
||||
```bash
|
||||
# one-time: git clone https://github.com/microsoft/vcpkg && ./vcpkg/bootstrap-vcpkg.sh (.bat on Windows)
|
||||
export VCPKG_ROOT=/path/to/vcpkg # works on Linux / macOS / Windows
|
||||
cmake --preset server-release # auto-installs deps pinned in vcpkg.json
|
||||
cmake --build --preset server-release
|
||||
```
|
||||
|
||||
Other useful toggles (pass with `-D` at configure time):
|
||||
|
||||
```bash
|
||||
cmake --preset dev -DVOICECAT_BUILD_SHARED=ON # build libvoicecat as a .dll/.so/.dylib (for the C# client)
|
||||
cmake --preset dev -DVOICECAT_BUILD_SERVER=OFF # core + tools only
|
||||
cmake --preset dev -DVOICECAT_BUILD_TESTS=OFF
|
||||
```
|
||||
|
||||
Formatting: `clang-format` config is `.clang-format` (Google base, 100 cols, 4-space).
|
||||
|
||||
```bash
|
||||
git ls-files '*.cpp' '*.h' | xargs clang-format -i
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture at a glance
|
||||
|
||||
Full detail: [`docs/architecture.md`](docs/architecture.md). The short version:
|
||||
|
||||
```
|
||||
Swift (macOS/iOS) ─┐ ┌─ C# (Windows)
|
||||
├──▶ libvoicecat (C ABI: voicecat.h) ◀──┤
|
||||
voicecat-server ───┘ net · crypto · codec · protocol · └─ all UIs are thin
|
||||
(links core) session · audio the core owns audio
|
||||
```
|
||||
|
||||
- **One core, many faces.** Protocol, Opus, crypto, networking, jitter buffer, and mixing
|
||||
live once in C++. Clients call the **C ABI** (`core/include/voicecat.h`); the server links
|
||||
the same core, so framing/crypto never drift between ends.
|
||||
- **Two transports.** TCP + **TLS 1.3** (control, protobuf `Envelope`) and UDP + **exported-key
|
||||
ChaCha20-Poly1305 AEAD** (media, fixed binary voice frame). Encryption is mandatory.
|
||||
- **Threading.** Real-time audio threads never allocate/lock/block; they exchange data with
|
||||
the net thread via lock-free ring buffers; a worker pool absorbs blocking work.
|
||||
|
||||
### Subsystem map (code ↔ design doc)
|
||||
|
||||
| Path | Subsystem | Design |
|
||||
|------|-----------|--------|
|
||||
| `core/include/voicecat.h` | The C ABI (client/server contract) | architecture.md §4 |
|
||||
| `core/proto/voicecat.proto` | Control-plane wire format (source of truth) | protocol.md |
|
||||
| `core/src/net/` | Asio TCP/UDP transport, `[u32 len][payload]` framing | protocol.md §1, voice.md §2 |
|
||||
| `core/src/crypto/` | TLS 1.3 (mbedTLS), media AEAD (libsodium), anti-replay | security.md |
|
||||
| `core/src/codec/` | Opus encode/decode, FEC/DTX | voice.md §3–4 |
|
||||
| `core/src/protocol/` | Envelope (de)serialize, request/response, dispatch | protocol.md |
|
||||
| `core/src/session/` | Channels, users, streams, permissions, ephemeral text | protocol.md §5 |
|
||||
| `core/src/audio/` | miniaudio I/O, APM DSP, jitter buffer, mixer | voice.md §8–11 |
|
||||
| `core/src/core/` | `vc_client` — the handle behind the C ABI | architecture.md §4 |
|
||||
| `server/` | Connection mgr, session registry, SFU relay, SQLite | architecture.md §5 |
|
||||
| `tools/vccli/` | Headless client that drives/verifies the protocol | — |
|
||||
| `clients/apple/`, `clients/windows/` | Native GUIs (M4) | architecture.md §4 |
|
||||
|
||||
---
|
||||
|
||||
## Documentation index (source of truth)
|
||||
|
||||
Read [`docs/`](docs/) before changing behavior. Order:
|
||||
|
||||
1. [docs/README.md](docs/README.md) — overview, locked decisions, glossary
|
||||
2. [docs/architecture.md](docs/architecture.md) — core, C ABI, threading, server
|
||||
3. [docs/protocol.md](docs/protocol.md) — control plane, Envelope, message catalog
|
||||
4. [docs/voice.md](docs/voice.md) — UDP media, Opus, multi-stream, two-sided NR, VAD/PTT
|
||||
5. [docs/security.md](docs/security.md) — mandatory encryption, TLS+AEAD, accounts, threat model
|
||||
6. [docs/tech-stack.md](docs/tech-stack.md) — libraries, permissive-license rule, tooling
|
||||
7. [docs/deployment.md](docs/deployment.md) — zero-config self-host (Docker / binary / source)
|
||||
8. [docs/roadmap.md](docs/roadmap.md) — milestones + resolved decisions
|
||||
|
||||
---
|
||||
|
||||
## Keeping track of progress
|
||||
|
||||
**[`PROGRESS.md`](PROGRESS.md) is the living status file.** When you finish a task, check it
|
||||
off there and note the next step, so the next agent can pick up instantly. Treat it as part of
|
||||
the work, not an afterthought — update it in the same commit as the code.
|
||||
|
||||
---
|
||||
|
||||
## House rules (hard constraints)
|
||||
|
||||
- **A clean compile is the floor, not the goal.** "Done" = the milestone's observable exit
|
||||
criterion in [`docs/roadmap.md`](docs/roadmap.md) passes (e.g. M1 = two `vccli` actually chat
|
||||
over TLS). Encode it as a test. See [`AGENTS.md`](AGENTS.md).
|
||||
- **No GPL/LGPL dependencies, ever** (closed-source redistribution is a goal). docs/tech-stack.md §5.
|
||||
- **Encryption is mandatory** — never add a plaintext transport path. docs/security.md.
|
||||
- **Real-time audio threads** never allocate, lock, or block. docs/architecture.md §3.
|
||||
- **Keep docs + code in sync.** Changing a wire format (`voicecat.proto`) or the C ABI
|
||||
(`voicecat.h`) is a deliberate, versioned act — update the doc in the same commit (protocol.md §8).
|
||||
- Every commit must build (`cmake --build --preset dev`) and pass `ctest --preset dev`.
|
||||
Reference in New Issue
Block a user