# Yonexus.Client — Development Conventions This document defines implementation conventions for the client repository. ## 1. Naming Conventions ### Files - use `camelCase.ts` for source files - use descriptive module names matching responsibility - avoid generic names like `utils.ts` unless the scope is extremely narrow and justified Examples: - `localState.ts` - `keys.ts` - `heartbeat.ts` - `onGatewayStart.ts` ### Types / Interfaces - use `PascalCase` Examples: - `LocalClientState` - `ClientRuntimeState` - `AuthProofPayload` ### Functions - use `camelCase` Examples: - `loadLocalState` - `signProofPayload` - `startHeartbeatLoop` ### Constants - use `UPPER_SNAKE_CASE` for exported constants Examples: - `HEARTBEAT_INTERVAL_MS` - `RECONNECT_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: ```ts interface YonexusClientError extends Error { code: string; details?: Record; } ``` ### Error Code Style - uppercase snake case - stable once published in logs/tools/docs Examples: - `INVALID_CONFIG` - `CONNECTION_FAILED` - `AUTH_FAILED` - `NOT_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-a` - `auth failed identifier=client-a reason=STALE_TIMESTAMP` - `heartbeat 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`, and `protocol/PROTOCOL.md` - keep runtime code understandable; do not spread core state transitions across too many files