MiningOS Logo
Contribute To MiningOS

Code Documentation Standards

This document defines the documentation standards for inline code comments, JSDoc annotations, module documentation, and API reference formatting across the MiningOS ecosystem.

For code style and linting requirements, see Testing & Linting Guidelines.


Overview

Well-documented code is essential for maintaining a complex distributed system like MiningOS. Documentation serves multiple audiences: contributors, future maintainers, API consumers, and operators configuring deployments.

Documentation Philosophy

MiningOS follows these documentation principles:

PrincipleDescription
Self-documenting code firstClear naming and structure reduce comment needs
Document the "why"Code shows "what" and "how"; comments explain "why"
Keep it currentOutdated documentation is worse than none
Audience-awareMatch detail level to the reader's needs

When to Document

Always Document

Consider Documenting

  • Complex algorithms
  • Non-obvious decisions
  • Performance optimizations
  • Workarounds and edge cases

Skip Documentation

  • Obvious operations
  • Self-explanatory getters or setters
  • Standard patterns
  • Trivial utility functions

File Headers

Every JavaScript file begins with 'use strict' followed by appropriate header documentation. For the complete file structure, see Repository Structure — Standard Directory Structure.

Standard Header Pattern

'use strict'

/**
 * @fileoverview Brief description of the file's purpose.
 * @module module-name
 */

Worker File Headers

Worker entry points include operational context:

'use strict'

/**
 * @fileoverview PowerMeter Rack Worker - Manages power monitoring devices.
 *
 * This worker handles:
 * - Device discovery and registration
 * - Real-time data (RTD) collection at 5-second intervals
 * - Snapshot aggregation at 60-second intervals
 * - Modbus communication with power meters
 *
 * @module rack.powermeter.wrk
 * @extends miningos-tpl-wrk-powermeter
 * @see {@link https://github.com/tetherto/miningos-tpl-wrk-powermeter}
 */

const WrkPowerMeterRack = require('miningos-tpl-wrk-powermeter')
// ...

For supported power meter models and specifications, see Supported Devices — Power Meters.

Library File Headers

Library modules document their exports and dependencies:

'use strict'

/**
 * @fileoverview Device controller for Schneider PM5340 power meters.
 *
 * Implements Modbus TCP communication for:
 * - Voltage, current, power readings
 * - Energy counters (import/export)
 * - Power quality metrics (THD, power factor)
 *
 * @module lib/schneider-pm5340
 * @requires modbus-tcp
 */

JSDoc Annotations

MiningOS uses JSDoc for function and class documentation. While Standard.js doesn't enforce JSDoc, consistent usage improves code navigation and IDE support.

Function Documentation

/**
 * Collects a snapshot from the specified device.
 *
 * @async
 * @param {Object} thg - The thing (device) object
 * @param {string} thg.id - Unique device identifier
 * @param {Object} thg.ctrl - Device controller instance
 * @param {Object} [thg.opts] - Device-specific options
 * @returns {Promise<Object>} Snapshot containing stats and config
 * @throws {Error} ERR_THING_NOTFOUND if device does not exist
 *
 * @example
 * const snap = await worker.collectThingSnap(device)
 * // Returns: { stats: {...}, config: {...}, timestamp: 1234567890 }
 */
async collectThingSnap(thg) {
    // Implementation
}

For error code conventions, see Contribution Workflow — Error Handling.

Class Documentation

/**
 * Represents a Whatsminer M56S miner controller.
 *
 * Handles communication with Whatsminer devices via the
 * proprietary API protocol (TCP port 4028).
 *
 * @class
 * @extends BaseMiner
 *
 * @property {string} address - Device IP address
 * @property {number} port - API port (default: 4028)
 * @property {number} timeout - Connection timeout in ms
 *
 * @example
 * const miner = new WhatsminerMiner({
 *   address: '192.168.1.100',
 *   port: 4028,
 *   password: 'admin'
 * })
 * await miner.connect()
 */
class WhatsminerMiner extends BaseMiner {
    // Implementation
}

For Whatsminer specifications, see Supported Devices — MicroBT Whatsminer.

Type Definitions

Define complex types for reuse across documentation:

/**
 * @typedef {Object} MinerStats
 * @property {number} hashrate_mhs - Current hashrate in MH/s
 * @property {number} power_w - Power consumption in watts
 * @property {Object} temperature_c - Temperature readings
 * @property {number} temperature_c.board - Board temperature
 * @property {number} temperature_c.chip - Chip temperature
 * @property {string} status - Operating status ('mining', 'idle', 'offline')
 */

/**
 * @typedef {Object} PoolConfig
 * @property {string} url - Pool URL (stratum+tcp://...)
 * @property {string} user - Pool username/worker
 * @property {string} [pass='x'] - Pool password
 */

For pool configuration in production, see Operator Manual — Pool Manager Module.

Common JSDoc Tags

TagUsageExample
@async*Async functions@async
@paramFunction parameters@param \{string\} id - Device ID
@returnsReturn value@returns \{Promise<Object>\}
@throwsPossible errors@throws \{Error\} ERR_INVALID_SOMETHING
@exampleUsage examplesSee above
@privateInternal methods@private
@deprecatedDeprecated features@deprecated Use newMethod instead
@seeRelated resources@see \{@link otherFunction\}
@sinceVersion introduced@since 1.2.0

*Available in JSDoc 3.5.0 and later

For more information and to learn about custom tags, check out the JSDoc official website.


Inline Comments

Inline comments explain non-obvious code behavior. They should add value beyond what the code already communicates.

When to Use Inline Comments

Use comments for:

The examples below highlight application of doctrine stated in Overview:

// Whatsminer requires a 200ms delay between commands
// to prevent API rate limiting
await sleep(200)

// MongoDB aggregation: group by container, sum hashrates
// $unwind expands the workers array for individual matching
const pipeline = [
    { $unwind: '$workers' },
    { $group: { _id: '$container', total: { $sum: '$hashrate' } } }
]

// Edge case: some S19 firmware returns temperature as string
const temp = typeof raw.temp === 'string' ? parseFloat(raw.temp) : raw.temp

Comment Style Guidelines

// GOOD: Explains why, not what
// Retry with exponential backoff to handle temporary network issues
for (let i = 0; i < 3; i++) {
    await sleep(Math.pow(2, i) * 1000)
}

// BAD: States the obvious
// Increment counter by 1
counter++

// BAD: Outdated comment (code changed, comment did not)
// Check if device is online
if (device.status === 'mining') { // Actually checks mining status now

Section Markers

Use section markers for long files to improve navigation:

// =============================================================================
// RPC Methods
// =============================================================================

async listThings(req) { /* ... */ }
async queryThing(req) { /* ... */ }

// =============================================================================
// Internal Helpers
// =============================================================================

_validateRequest(req) { /* ... */ }
_formatResponse(data) { /* ... */ }

// =============================================================================
// Lifecycle Methods
// =============================================================================

async _start(cb) { /* ... */ }
async _stop(cb) { /* ... */ }

Anti-Patterns to Avoid

Anti-PatternExampleProblem
Commented-out code// await oldMethod()Use version control instead
Journal comments// Fixed bug - John 2024-01-15Use git history (see Branching & PR Conventions
Noise comments// End of functionAdds no value
Lying commentsComment says X, code does YMisleads readers
Excessive commentsEvery line commentedObscures the code

Constants Documentation

Constants files serve as authoritative references for magic values throughout the codebase.

Constant Object Documentation

'use strict'

/**
 * @fileoverview Mining operation constants and configuration values.
 * @module lib/constants
 */

/**
 * Default nominal efficiency ratings by miner model (W/TH).
 * Used for power estimation when actual readings are unavailable.
 *
 * Values sourced from manufacturer specifications:
 * - Bitmain: https://shop.bitmain.com/
 * - MicroBT: https://www.microbt.com/
 *
 * @type {Object.<string, number>}
 */
const DEFAULT_NOMINAL_EFFICIENCY_WTHS = {
    'miner-am-s19xp_h': 20.8,  // Antminer S19 XP Hyd
    'miner-am-s19xp': 21,      // Antminer S19 XP
    'miner-am-s21': 17.5,      // Antminer S21
    'miner-am-s21pro': 17,     // Antminer S21 Pro
    'miner-wm-m56s': 22,       // Whatsminer M56S
    'miner-av-a1346': 30       // Avalon A1346
}

For the complete list of supported models and specifications, see Supported Devices.

Enumeration-Style Constants

/**
 * Device operational states.
 * These values are used across all device types for status reporting.
 *
 * @readonly
 * @enum {string}
 */
const MINER_STATUS = {
        /** Miner is unreachable or not responding */
        OFFLINE: 'offline',
        /** Miner is in low-power sleep mode */
        SLEEPING: 'sleeping',
        /** Miner is actively mining/operating */
        MINING: 'mining',
        /** Miner reported an error condition */
        ERROR: 'error',
        /** Miner is powered but not operating */
        NOT_MINING: 'not_mining'
    }

For how these statuses appear in the UI, see Operator Manual — Explorer.

Configuration Constants

/**
 * Time intervals used throughout the system.
 * All values are in milliseconds unless otherwise noted.
 * @namespace
 */
const intervals = {
        /** Snapshot collection interval (60 seconds) */
        collectSnapMs: 60 * 1000,
        /** RTD collection interval (5 seconds) - power meters only */
        collectRTDMS: 5 * 1000,
        /** Log rotation check interval (2 minutes) */
        rotateLogsMs: 2 * 60 * 1000,
        /** Action timeout for voting system (24 hours) */
        actionTimeoutMs: 24 * 60 * 60 * 1000
    }

README Documentation

Every repository requires a README.md with standardized sections. For the complete repository structure, see Repository Structure.

README Structure

# repository-name

Brief description of the worker's purpose.

## Overview
Extended description including:
- Position in inheritance hierarchy (see [Architecture](../about-miningos/architecture)
- Key responsibilities
- Supported device types/models (see [Supported Devices](../about-miningos/supported-devices)

## Dependencies
- Parent worker: `miningos-tpl-wrk-<type>`
- External services: List any APIs, protocols
- System requirements: Node.js version, OS

## Installation
[Installation steps - see Installation Guide](../install-miningos)

## Configuration
[Configuration file documentation]

## Usage
[Startup commands, CLI examples]

## RPC API Reference
[Full RPC method documentation]

## Development
[Test commands, adding features - see Testing & Linting Guidelines](./testing-and-linting-guidelines)

## Troubleshooting
[Common issues and solutions]

## License
[License information - see License Section below]

API Reference Sections

Structure RPC documentation consistently. Example with a single method:

## RPC API Reference

### Read Operations

#### `listThings`

Returns all registered device IDs.

**Operation:** Read

**Request:**
```json
\{\}
```

**Response:**

```json
["miner-001", "miner-002", "miner-003"]
```

**Errors:** None

Code Examples in README

Provide practical, copy-paste-ready examples:

### Example: Register and Query a Miner

```bash
# 1. Register the miner
hp-rpc-cli -s $WORKER_PUBKEY -m registerThing -d '\{
  "id": "s19-rack1-01",
  "addrIPv4": "192.168.1.100",
  "opts": \{ "port": 4028, "password": "admin" \},
  "info": \{ "position": "rack-1-slot-1", "container": "container-a" \},
  "tags": ["production", "building-1"]
\}'

# 2. Verify registration
hp-rpc-cli -s $WORKER_PUBKEY -m getThing -d '\{"id": "s19-rack1-01"\}'

# 3. Collect current stats
hp-rpc-cli -s $WORKER_PUBKEY -m queryThing -d '\{
  "id": "s19-rack1-01",
  "method": "getStats"
\}'
```

For complete RPC registration examples, see Installation Guide — Register Workers.

Above, an example of Markdown syntax for copy-paste-ready excerpt for code in bash (for convenience, the example itself is in copy-paste-ready format).

License Section

All MiningOS repositories must include a License section and be released under the Apache License 2.0. This is mandatory for ecosystem consistency and legal clarity.

Required License Section Format

## License

This project is licensed under the Apache License 2.0 - see the [LICENSE](https://www.apache.org/licenses/LICENSE-2.0.html) file for details.

Copyright © [YEAR] Tether Operations Limited

The Apache 2.0 license was chosen for MiningOS to enable broad adoption while providing patent protection and requiring attribution. All contributions to MiningOS repositories are subject to this license.


Error Message Documentation

Consistent error documentation helps operators diagnose issues quickly. For error handling patterns in code, see Contribution Workflow — Error Handling.

Error Code Registry

Maintain a central error code reference:

/**
 * @fileoverview Error codes used across MiningOS workers.
 *
 * Error code format: ERR_{CATEGORY}_{SPECIFIC}
 *
 * Categories:
 * - THING: Device-related errors
 * - RACK: Worker registration errors
 * - ACTION: Action/voting system errors
 * - PARAM: Parameter validation errors
 * - PERM: Permission errors
 */

/**
 * Error codes and their descriptions.
 * @type {Object.<string, string>}
 */
const ERROR_CODES = {
  // Thing errors
  ERR_THING_ID_INVALID: 'Device ID is missing or not a valid UUID',
  ERR_THING_NOTFOUND: 'Device with specified ID is not registered',
  ERR_THING_OFFLINE: 'Device is not responding to API requests',

  // Permission errors
  ERR_SLAVE_BLOCK: 'Write operations are not allowed on slave nodes',
  ERR_MISSING_WRITE_PERMISSIONS: 'Client lacks write permission for this operation',

  // Action errors
  ERR_ACTION_NOTFOUND: 'Action ID does not exist',
}

For how errors appear in the operator interface, see Operator Manual — Alerts Manual.

Error Context

When throwing errors, include helpful context:

// GOOD: Error with context
if (!this.mem.things[req.id]) {
  const err = new Error('ERR_THING_NOTFOUND')
  err.context = { requestedId: req.id, availableCount: Object.keys(this.mem.things).length }
  throw err
}

// GOOD: Descriptive error for debugging
if (response.status !== 200) {
  throw new Error(`ERR_DEVICE_API_FAILED: ${response.status} - ${response.statusText}`)
}

Documentation Maintenance

Documentation Review Checklist

Before submitting a PR (see Branching & PR Conventions — PR Checklist), verify documentation is complete:

  • New RPC methods have JSDoc annotations
  • New RPC methods are documented in README
  • Error codes are added to error registry
  • Constants have descriptive comments
  • Configuration options are documented
  • Complex logic has explanatory comments
  • No commented-out code remains
  • No outdated comments exist
  • Examples are tested and working
  • LICENSE file present and correct

On this page