4.5 KiB
4.5 KiB
Yonexus.Client — Development Conventions
This document defines implementation conventions for the client repository.
1. Naming Conventions
Files
- use
camelCase.tsfor source files - use descriptive module names matching responsibility
- avoid generic names like
utils.tsunless the scope is extremely narrow and justified
Examples:
localState.tskeys.tsheartbeat.tsonGatewayStart.ts
Types / Interfaces
- use
PascalCase
Examples:
LocalClientStateClientRuntimeStateAuthProofPayload
Functions
- use
camelCase
Examples:
loadLocalStatesignProofPayloadstartHeartbeatLoop
Constants
- use
UPPER_SNAKE_CASEfor exported constants
Examples:
HEARTBEAT_INTERVAL_MSRECONNECT_MAX_DELAY_MS
2. Module Boundaries
plugin/index.ts
- wiring only
- no business logic
plugin/core/
- reusable domain logic
- local state handling
- key generation/signing
- pairing/auth/heartbeat rules
- dispatch behavior
servers/
- runtime/service bootstrap code
- WebSocket client lifecycle
- reconnect/backoff orchestration
plugin/hooks/
- OpenClaw lifecycle integration
- should call into core/runtime modules, not reimplement logic
plugin/tools/
- thin wrappers over core/runtime capabilities
- no duplication of business rules already implemented in core
plugin/commands/
- operator-facing orchestration layer
- should not directly mutate local state bypassing core rules
3. Error Conventions
Error Shape
Use structured errors rather than throwing untyped strings.
Recommended shape:
interface YonexusClientError extends Error {
code: string;
details?: Record<string, unknown>;
}
Error Code Style
- uppercase snake case
- stable once published in logs/tools/docs
Examples:
INVALID_CONFIGCONNECTION_FAILEDAUTH_FAILEDNOT_AUTHENTICATED
Error Messages
- concise
- operator-readable
- do not leak secrets, private keys, raw proofs, or unsafe internal details
4. Logging Conventions
General Rule
Logs should help operators debug connection/auth issues without exposing secrets.
Must Never Log in Plaintext
notifyBotToken- local
secret - private key material
- raw signed proof payload
- human-provided pairing code
Preferred Log Fields
When possible, log structured context such as:
identifier- event type
- connection state transition
- reason code
- timestamp
Example Good Logs
connecting to mainHost for identifier=client-aauth failed identifier=client-a reason=STALE_TIMESTAMPheartbeat loop started identifier=client-a
5. Protocol Usage Conventions
- treat
protocol/submodule as the source of truth - do not implement local protocol deviations without updating
Yonexus.Protocol - if client behavior reveals a protocol gap, fix protocol docs rather than hiding the difference in client-only logic
6. Local State Conventions
- keep persisted local state explicit and versionable
- separate long-lived trust data from transient connection runtime state
- avoid implicit mutation of local state from multiple unrelated modules
- persist changes through explicit state APIs rather than ad-hoc file writes
7. Reconnect Conventions
- reconnect behavior should be explicit and observable
- use bounded backoff
- stop background timers cleanly on disconnect
- avoid overlapping reconnect attempts
8. Pairing / Auth Conventions
- treat pairing, auth, and re-pair transitions as explicit states
- do not silently reuse stale secrets after
re_pair_required - proof construction and signing should be deterministic and testable
- keep signing and local key handling isolated in dedicated modules
9. Command / Tool Conventions
- commands and tools should surface operator-safe summaries
- commands should call core/runtime services, not modify raw state directly
- sending before authentication should fail clearly unless explicit queueing is designed later
10. Testing Conventions
- write unit tests for local state, signing, and routing first
- reserve integration tests for connection/pairing/auth flows
- test negative paths deliberately:
- connection failure
- invalid auth response
- forced re-pair
- heartbeat stop/start
- malformed builtin payload
11. Change Discipline
When implementing:
- update docs when behavior changes
- avoid silent divergence from
PLAN.md,TASKS.md, andprotocol/PROTOCOL.md - keep runtime code understandable; do not spread core state transitions across too many files