# Yonexus.Server — Development Conventions This document defines implementation conventions for the server 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: - `registry.ts` - `pairing.ts` - `heartbeat.ts` - `onGatewayStart.ts` ### Types / Interfaces - use `PascalCase` Examples: - `ClientRecord` - `PairingState` - `ServerRuntime` ### Functions - use `camelCase` Examples: - `loadRegistry` - `verifyAuthProof` - `sendPairingNotification` ### Constants - use `UPPER_SNAKE_CASE` for exported constants Examples: - `HEARTBEAT_INTERVAL_MS` - `AUTH_WINDOW_SECONDS` --- ## 2. Module Boundaries ### `plugin/index.ts` - wiring only - no business logic ### `plugin/core/` - reusable domain logic - state transitions - validation - auth/pairing/heartbeat rules ### `servers/` - network/runtime bootstrapping - WebSocket transport lifecycle - active connection management ### `plugin/hooks/` - OpenClaw lifecycle integration - should call into core/runtime modules, not reimplement logic ### `plugin/tools/` - thin wrappers over core/runtime capabilities - do not duplicate business rules already implemented in core ### `plugin/commands/` - operator-facing orchestration layer - no core logic duplication --- ## 3. Error Conventions ### Error Shape Use structured errors rather than throwing untyped strings. Recommended shape: ```ts interface YonexusServerError extends Error { code: string; details?: Record; } ``` ### Error Code Style - uppercase snake case - stable once published in logs/tools/docs Examples: - `INVALID_CONFIG` - `IDENTIFIER_NOT_ALLOWED` - `PAIRING_EXPIRED` - `NONCE_COLLISION` ### Error Messages - concise - operator-readable - do not leak secrets, tokens, raw proofs, or private internal state --- ## 4. Logging Conventions ### General Rule Logs should be useful for operators and safe for production. ### Must Never Log in Plaintext - `notifyBotToken` - client `secret` - raw pairing code after issuance - raw signed proof payload - any private key material ### Preferred Log Fields When possible, log structured context such as: - `identifier` - event type - status transition - reason code - timestamp ### Example Good Logs - `pairing started for identifier=client-a` - `auth failed for identifier=client-a reason=NONCE_COLLISION` - `status changed identifier=client-a online->unstable` --- ## 5. Protocol Usage Conventions - treat `protocol/` submodule as the source of truth - do not fork protocol semantics locally without updating `Yonexus.Protocol` - if implementation pressure suggests protocol change, change protocol repo first or in the same coordinated step --- ## 6. Persistence Conventions - prefer explicit versionable JSON structures for initial persistence - keep persisted schema clear and documented - do not mix transient socket/session state into long-lived persisted records unless intentional - keep rolling replay/rate-limit windows separate from durable trust records where practical --- ## 7. State Machine Conventions - keep state transitions explicit - avoid hidden/implicit mutations across unrelated modules - centralize transitions for pairing/auth/liveness when possible - treat `re_pair_required` as a first-class transition, not an ad-hoc side effect --- ## 8. Command / Tool Conventions - commands and tools should surface operator-safe summaries - raw internal state should be exposed carefully - commands should call core/runtime services, not manipulate registry internals directly --- ## 9. Testing Conventions - write narrow unit tests for deterministic logic first - reserve integration tests for protocol flow and socket lifecycle - test negative paths deliberately: - invalid pairing code - stale timestamp - nonce collision - excessive handshake attempts - heartbeat timeout --- ## 10. Change Discipline When implementing: - update docs when architecture/protocol behavior changes - avoid silent divergence from `PLAN.md`, `TASKS.md`, and `protocol/PROTOCOL.md` - prefer fewer clear modules over many shallow wrappers