- Use snake_case for all JSON keys
- Examples:
session_id,working_directory,claude_session_id
- Use kebab-case for all keywords and identifiers
- Examples:
:session-id,:working-directory,:claude-session-id
- Parse JSON → Clojure: Convert
snake_casekeys tokebab-casekeywords - Generate Clojure → JSON: Convert
kebab-casekeywords tosnake_casekeys - Use Cheshire's
:key-fnoption for automatic conversion
- Use camelCase for Swift properties (Swift convention)
- Use snake_case for JSON communication with backend
- Examples: Swift
claudeSessionId↔ JSONsession_id↔ Clojure:session-id
All UUIDs must be lowercase across the entire system.
- iOS: Always use
.lowercased()when converting UUIDs to strings- Correct:
session.id.uuidString.lowercased() - Incorrect:
session.id.uuidString(produces uppercase)
- Correct:
- Backend: Store and compare UUIDs as lowercase strings without normalization
- Rationale: Eliminates case-sensitivity bugs, ensures consistent logging/debugging, prevents issues on case-sensitive filesystems
- Session Migration: VoiceCodeClient automatically migrates existing sessions on init to ensure
backendNamecontains the UUID (not a display name)
iOS (Swift):
// Creating/sending session IDs
let sessionId = session.id.uuidString.lowercased()
client.subscribe(sessionId: session.id.uuidString.lowercased())
// Always lowercase in JSON payloads
message["session_id"] = session.id.uuidString.lowercased()Backend (Clojure):
;; Session IDs arrive lowercase from iOS, use directly
(get @session-index session-id) ; No str/lower-case needed
;; Filesystem .jsonl filenames are lowercase
;; e.g., ~/.claude/projects/mono/abc123de-4567-89ab-cdef-0123456789ab.jsonlLogs:
✓ Correct: "Subscribing to session: abc123de-4567-89ab-cdef-0123456789ab"
✗ Wrong: "Subscribing to session: ABC123DE-4567-89AB-CDEF-0123456789AB"
The WebSocket protocol (message types, connection flow, error handling, command execution) and HTTP API authentication live in docs/protocol/websocket-protocol.md. That doc is intentionally not auto-imported into Claude context — open it on demand when working on the protocol surface.
Background design docs in docs/design/ are reference material, not auto-imported. Open them on demand:
docs/design/append-only-message-stream.md— v0.4.0 monotonic-seq stream designdocs/design/canonical-message-wire-format.md— message shape across providersdocs/design/websocket-reconnection-fix.md— reconnect race fixesdocs/design/refresh-session-list-fix.md—refresh_sessionsmessage rationale