Skip to main content

Documentation Contribution Guide

Contributing

Documentation Contribution Guide

This page explains how to write and maintain documentation for EnerOS, including this website (eneros-web) and crate-embedded documentation (cargo doc). EnerOS documentation is a key entry point for users and developers to understand the system; high-quality documentation is as important as high-quality code.

Document Types

EnerOS documentation is divided into the following types by audience and purpose:

TypeLocationAudienceWriting Style
Concept Docssrc/content/docs/concepts/New usersIntuitive, explanatory
Quick Startsrc/content/docs/quick-start/First-time usersStep-by-step, follow-along
Architecture Docssrc/content/docs/architecture/ArchitectsRigorous, structured
Capability Docssrc/content/docs/capabilities/IntegratorsScenario-based, comparative
Tutorialssrc/content/docs/tutorials/DevelopersEnd-to-end, practical
Compliance Docssrc/content/docs/compliance/Security & complianceRigorous, clause-style
ADRsrc/content/docs/adr/EveryoneDecision record style
API Referencesrc/content/docs/api-reference/IntegratorsConcise, reference style
Crate Indexsrc/content/docs/crates/API usersOverview style
Crate Docs/// comments + cargo docAPI usersStandard rustdoc
Project Docsdocs/EveryoneFree-form
READMERepository rootNew visitorsOverview style

Document Audience Matrix

Different documents target different readers; clarify the audience before writing:

AudienceFocusRecommended Entry
Decision MakersValue, ROI, casesREADME, concept docs
ArchitectsDesign philosophy, scalabilityArchitecture docs, ADR
Integration DevelopersAPI, SDK, configurationQuick start, API reference
Application DevelopersTutorials, examplesTutorials, capability docs
OperationsDeployment, monitoring, HADeployment docs, compliance docs
Security ComplianceCompliance, auditingCompliance docs, security sections
ContributorsProcess, standardsContributing guide

Document Structure

Standard Structure

Each document should follow this structure:

  1. Frontmatter: Metadata (title, description, category, order)
  2. H1 Heading: Consistent with title
  3. Lead paragraph: 1-3 sentences explaining the document’s purpose and audience
  4. Body: Elaborate in sections, using H2 / H3 headings
  5. Examples: Complete runnable code or configuration
  6. Checklist: Checkable items for key operations
  7. Related Documentation: Cross-links

Heading Hierarchy Standards

LevelCountPurposeExample
#1 (consistent with title)Document main title# Testing Standards
##3-8Major sections## Test Layering
###As neededSubsections### Unit Tests
####Use sparinglyFine-grained sections#### Naming Conventions

Rules:

  • Do not skip heading levels (don’t jump from ## directly to ####)
  • Keep blank lines before and after headings
  • Use nouns or verb-object phrases for headings, avoid questions
  • Do not end headings with punctuation

Paragraphs and Lists

  • Blank line between paragraphs
  • No blank lines between list items (unless items contain multiple paragraphs)
  • Use ordered lists for steps, unordered lists for parallel items
  • Keep blank lines before and after lists

Frontmatter Standards

All Markdown files must contain frontmatter:

---
title: "Document Title"
description: "One-sentence description"   # Optional but recommended
category: "Quick Start"          # Must match sidebar group
order: 3                      # Sort order within category
---

Field Descriptions

FieldRequiredTypeDescription
titleYesstringDocument title, must match the first # Heading
descriptionRecommendedstringOne-sentence description, used for SEO and card display
categoryYesstringCategory name, must match sidebar group
orderYesnumberSort order within category, starting from 1

Categories and Order

CategoryDocument CountOrder Range
Quick Start61-6
Concepts61-6
Architecture Design41-4
Capabilities171-17
Tutorials61-6
Contributing Guide51-5
Compliance61-6
ADRAs neededAuto-increment
API Reference71-7
Crate91-9

Complete Example

---
title: "Testing Standards"
description: "Test layering and cargo test usage"
category: "Contributing Guide"
order: 3
---

# Testing Standards

EnerOS has 7300+ test cases covering all core functionality. This page details test layering, writing standards, and CI process.

## Test Layering

...

Writing Standards

Language

  • Primary language: Chinese first
  • Proper nouns kept in English: mTLS, SCADA, RTU, IEC 61850, GraphQL, WebSocket, SSE, Token, Cookie
  • Abbreviations given full form on first occurrence: Load Flow (PF), Energy Management System (EMS)
  • Numbers and units: Arabic numerals + SI units, e.g., 12ms, 100kW, 1.06 p.u.
  • Mixed Chinese-English: Add space between Chinese and English, e.g., “written in Rust”
  • Punctuation: Chinese uses full-width punctuation, code and numbers use half-width

Code Blocks

  • Must specify language: ```rust, ```bash, ```toml, ```yaml, ```json, ```sql
  • Keep blank lines before and after code blocks
  • Code examples must be runnable or compilable; avoid pseudocode
  • Long code blocks (>30 lines) should be split into multiple, with step-by-step explanations
  • Command-line examples use $ prefix or comment explanation
# Install dependencies
sudo apt install -y libssl-dev

# Build the project
cargo build --release
  • Internal links use relative paths: [Testing Standards](/docs/contributing/testing)
  • Avoid hardcoding domains (except GitHub repository and documentation site homepage)
  • Link text should be meaningful, avoid “click here”
  • Check link validity, avoid 404
# Correct
See [Testing Standards](/docs/contributing/testing) for details.

# Wrong
See [here](/docs/contributing/testing) for details.

Tables

  • Use for comparisons, mappings, parameter descriptions; better than long paragraphs
  • Concise headers, each column aligned
  • Short cell content, detailed explanations in paragraphs
  • Split complex tables into multiple
ParameterTypeDefaultDescription
hoststring0.0.0.0Listen address
portnumber8080Listen port
workersnumber4Worker thread count

Emphasis

  • Bold: For emphasizing keywords, warnings
  • Italic: For first occurrence of terms, foreign words
  • Inline code: For code identifiers, filenames, commands, parameter names
  • Avoid overusing emphasis; at most 1-2 per paragraph

Callouts

Use blockquotes for tips, warnings, notes:

> **Tip**: Using `cargo nextest run` is faster than `cargo test`.

> **Warning**: Be sure to change `hmac_key` in `audit.toml` in production environments.

> **Note**: Real-time domain features are fully supported only on Linux.

Example Code Standards

  • Must be runnable or compilable; avoid pseudocode and ellipsis
  • Do not use // ... to omit key logic
  • Include complete use statements and imports
  • Complex examples shown step by step, each step independently verifiable
// Correct: complete example
use eneros_powerflow::{NewtonRaphsonSolver, PowerflowResult};
use eneros_topology::Topology;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let topo = Topology::from_ieee_14bus();
    let solver = NewtonRaphsonSolver::new(50, 1e-8);
    let result: PowerflowResult = solver.solve(&topo)?;
    println!("Converged: {}", result.converged);
    Ok(())
}

// Wrong: using ellipsis
// fn main() {
//     let topo = ...;
//     let result = solver.solve(...);
//     ...
// }

Glossary

Key terms on first occurrence should provide full form and abbreviation:

ChineseEnglish Full FormAbbreviation
潮流计算Power FlowPF
经济调度Economic DispatchED
故障定位隔离与供电恢复Fault Detection, Isolation and Service RestorationFDIR
能量管理系统Energy Management SystemEMS
监控与数据采集Supervisory Control and Data AcquisitionSCADA
配电管理系统Distribution Management SystemDMS
虚拟电厂Virtual Power PlantVPP

Crate Embedded Documentation Standards

Doc Comments

Public APIs must have doc comments ///, verified via cargo doc:

/// Solves the load flow equations for a given topology.
///
/// Uses the Newton-Raphson iterative method, with maximum iterations controlled by `max_iterations`.
/// Convergence is considered when the voltage difference between two consecutive iterations is less than `tolerance`.
///
/// # Arguments
/// - `topology`: Grid topology, must have completed island detection
/// - `max_iterations`: Maximum iteration count, recommended 20-50
/// - `tolerance`: Convergence tolerance, default 1e-8
///
/// # Returns
/// Returns [`PowerflowResult`], containing voltage, phase angle, and branch power for each bus.
///
/// # Errors
/// - [`PowerflowError::NonConvergence`]: Iteration count exceeded without convergence
/// - [`PowerflowError::InvalidTopology`]: Topology data incomplete or contains loops
///
/// # Examples
///
/// ```rust
/// use eneros_powerflow::{NewtonRaphsonSolver, PowerflowResult};
/// use eneros_topology::Topology;
///
/// let topo = Topology::from_ieee_14bus();
/// let solver = NewtonRaphsonSolver::new(20, 1e-8);
/// let result: PowerflowResult = solver.solve(&topo).unwrap();
/// assert!(result.converged);
/// ```
pub fn solve(&self, topology: &Topology) -> Result<PowerflowResult> {
    unimplemented!()
}

rustdoc Sections

SectionPurposeRequired
# ArgumentsParameter descriptionRecommended
# ReturnsReturn value descriptionRecommended
# ErrorsError condition descriptionYes (when returning Result)
# PanicsPanic condition descriptionYes (when may panic)
# ExamplesRunnable examplesRecommended
# Safetyunsafe safety descriptionYes (for unsafe functions)
# See AlsoRelated API linksOptional

Module Documentation

lib.rs and mod.rs should have //! module documentation at the top:

//! # EnerOS Power Flow
//!
//! Grid load flow calculation module, supporting Newton-Raphson and fast decoupled methods.
//!
//! ## Overview
//!
//! - [`NewtonRaphsonSolver`]: Newton-Raphson method, fast convergence but computationally intensive
//! - [`FastDecoupledSolver`]: Fast decoupled method, suitable for distribution networks
//!
//! ## Examples
//!
//! ```rust
//! use eneros_powerflow::NewtonRaphsonSolver;
//! use eneros_topology::Topology;
//!
//! let topo = Topology::from_ieee_14bus();
//! let solver = NewtonRaphsonSolver::new(50, 1e-8);
//! let result = solver.solve(&topo).unwrap();
//! ```

Doc Tests

Example code in cargo doc is executed as tests:

# Run all doc tests
cargo test --doc --workspace

# Run doc tests for a specific crate
cargo test --doc -p eneros-powerflow

Doc test requirements:

  • Code must compile
  • Use # to hide unnecessary lines (e.g., # use ...)
  • Use no_run to skip execution but verify compilation: ```rust,no_run
  • Use ignore to skip entirely: ```rust,ignore
  • Use should_panic to verify panic: ```rust,should_panic
/// ```rust,no_run
/// # use eneros_powerflow::NewtonRaphsonSolver;
/// // This code will compile but not run
/// let solver = NewtonRaphsonSolver::new(50, 1e-8);
/// ```

Translation Guide

Supported Languages

EnerOS documentation currently supports the following languages:

LanguageCodeStatusMaintainer
Simplified Chinesezh-CNCompleteCore team
Englishen-USIn progressCommunity
日本語ja-JPIn progressCommunity
Españoles-ESStartingCommunity

Translation Process

  1. Claim a task: Filter by i18n label in GitHub Issues, comment to claim
  2. Base on latest main: Pull the latest code to avoid being out of sync with the original
  3. Translate: Keep code blocks as-is; only translate comments and explanatory text
  4. Proofread: Native speaker proofreading to ensure terminology accuracy
  5. Submit PR: Title prefixed with [i18n], e.g., [i18n] Translate testing.md to English

Translation Standards

  • Keep code blocks as-is: Do not translate code, commands, configuration, file paths
  • Code comments: Can be translated, but keep // or # prefix
  • Proper nouns: Keep in English, e.g., mTLS, SCADA, Rust, Cargo
  • Links: Internal links unchanged; external links can be replaced with corresponding language versions
  • frontmatter: Translate title and description; keep category and order unchanged
  • Terminology consistency: Refer to glossary, maintain consistency with already translated docs

Fluent Localization

The eneros-i18n crate uses Fluent to manage UI text, with translation files in locales/:

locales/
├── en-US.ftl    # English
├── zh-CN.ftl    # Simplified Chinese
├── ja-JP.ftl    # Japanese
└── es-ES.ftl    # Spanish

.ftl file example:

# locales/zh-CN.ftl
powerflow-solving = 正在求解潮流...
powerflow-converged = 潮流计算收敛,迭代 { $iterations }
powerflow-failed = 潮流计算失败:{ $error }

# locales/en-US.ftl
powerflow-solving = Solving power flow...
powerflow-converged = Power flow converged in { $iterations } iterations
powerflow-failed = Power flow failed: { $error }

Documentation Build and Preview

Local Preview

The EnerOS documentation site is built with Fumadocs using Next.js:

cd eneros-web
npm install
npm run dev    # Start dev server, visit http://localhost:3000

Build Production Version

cd eneros-web
npm run build  # Build production version
npm run start  # Start production server

Common build failure causes:

ErrorCauseSolution
frontmatter field type mismatchorder should be number not stringFix YAML
Code block language not specified``` missing language identifierAdd rust / bash etc.
Relative link 404Wrong link pathFix link path
Heading level skipJumping from ## to ####Add intermediate levels
frontmatter missingFile doesn’t include --- blockAdd frontmatter

Validate Documentation

# Validate all Markdown files contain frontmatter
cd eneros-web
npm run lint

# Check link validity
npm run check-links

# Type check
npm run typecheck

Cargo Doc Build

# Build all crate documentation
cargo doc --no-deps --all-features

# Build documentation for a specific crate
cargo doc --no-deps -p eneros-powerflow

# Open in browser
cargo doc --no-deps --open

# Build and run doc tests
cargo test --doc --workspace

Deployment

The documentation site is deployed on GitHub Pages, automated by .github/workflows/deploy-web.yml:

TriggerDeployment TargetURL
Push to main (affecting eneros-web/)GitHub Pageshttps://www.openeneros.com
Create tagGitHub Releasehttps://github.com/Gawg-AI/EnerOS/releases
Manual triggerPreview environmentTemporary URL

ADR Contribution

New architecture decisions must follow the ADR Overview format.

ADR Template

---
title: "ADR 0015: Short Title"
description: "Architecture Decision Record"
category: "ADR"
order: 15
---

# ADR 0015: Short Title

- **Status**: Proposed / Accepted / Deprecated / Superseded
- **Date**: 2026-07-06
- **Decision Makers**: Core team

## Context

(Describe the background, problems, and constraints that prompted this decision)

## Decision

(Describe the specific decision made)

## Alternatives

(List other options considered and their pros and cons)

## Consequences

- **Positive**: ...
- **Negative**: ...
- **Neutral**: ...

## References

- [Related ADR](/docs/adr/0002-power-native-agentos)
- [External Resource](https://example.com)

ADR Submission Process

  1. Create a new file in src/content/docs/adr/, with auto-incrementing number
  2. Register in the src/content/docs/adr/index.md list
  3. Submit PR with title docs(adr): add ADR 0015 ...
  4. At least one architect Review
  5. Status becomes “Accepted” after merge

Complete Documentation Example

The following is a complete capability document example, demonstrating the application of various standards:

---
title: "Load Flow Capability"
description: "EnerOS Load Flow engine capabilities, interfaces, and examples"
category: "Capabilities"
order: 3
---

# Load Flow Capability

EnerOS provides a high-performance Load Flow (Power Flow) engine, supporting Newton-Raphson and fast decoupled methods, suitable for transmission and distribution network analysis. This page introduces its capabilities, interfaces, and usage examples.

## Supported Solver Methods

| Method | Applicable Scenario | Convergence | Performance |
|--------|---------------------|-------------|-------------|
| Newton-Raphson | Transmission networks, strongly coupled systems | Strong | Medium |
| Fast Decoupled | Distribution networks, radial systems | Medium | High |
| DC Power Flow | Planning, approximate analysis | Weak | Very High |

## API Usage

### Rust API

```rust
use eneros_powerflow::{NewtonRaphsonSolver, PowerflowResult, PowerflowError};
use eneros_topology::Topology;
use std::time::Duration;

fn main() -> Result<(), PowerflowError> {
    // Load IEEE 14-bus standard test system
    let topo = Topology::from_ieee_14bus();

    // Create solver
    let solver = NewtonRaphsonSolver::new(50, 1e-8);

    // Solve
    let result: PowerflowResult = solver.solve(&topo)?;

    // Output results
    println!("Converged: {}", result.converged);
    println!("Iterations: {}", result.iterations);
    for bus in &result.buses {
        println!(
            "Bus {}: V = {:.4} p.u., θ = {:.4} rad",
            bus.id, bus.voltage_magnitude, bus.voltage_angle
        );
    }

    Ok(())
}
```

### REST API

```bash
# Solve load flow
curl -X POST http://localhost:8080/api/powerflow/solve \
    -H "Content-Type: application/json" \
    -d @ieee14.json

# Expected response
# {
#   "converged": true,
#   "iterations": 4,
#   "buses": [
#     {"id": 1, "v": 1.06, "theta": 0.0},
#     ...
#   ]
# }
```

## Performance Metrics

| Test Case | Node Count | Average Latency | Memory Usage |
|-----------|------------|-----------------|--------------|
| IEEE 14-bus | 14 | < 12ms | 2 MB |
| IEEE 30-bus | 30 | < 18ms | 4 MB |
| IEEE 118-bus | 118 | < 45ms | 12 MB |
| IEEE 300-bus | 300 | < 120ms | 28 MB |

## Limitations and Constraints

- Input topology must have completed island detection
- Slack bus must exist and be unique
- Node voltages must be in the [0.5, 1.5] p.u. range

> **Warning**: When load flow does not converge, `PowerflowError::NonConvergence` is returned; the caller should handle this error instead of unwrap.

## Checklist

- [ ] Topology has completed island detection
- [ ] Slack bus is set
- [ ] No duplicate node numbers
- [ ] Impedance parameters are non-zero

## Related Documentation

- [Grid Topology](/docs/capabilities/grid-topology) - Topology engine
- [Security Constraints](/docs/capabilities/physics-constraint) - Constraint engine
- [Load Flow Tutorial](/docs/tutorials/load-flow) - Complete tutorial
- [API Reference](/docs/api-reference/rest) - REST API

Documentation Contribution Checklist

Please check each item before submitting a documentation PR:

  • frontmatter is complete (title / description / category / order)
  • title matches the first # Heading
  • Heading levels do not skip
  • Code blocks specify language
  • Code examples are runnable or compilable (no // ... omissions)
  • Internal links use relative paths
  • Links are valid, no 404
  • Table fields are complete, no missing columns
  • Spaces between Chinese and English
  • Terms given full form on first occurrence
  • npm run build passes
  • cargo doc --no-deps passes (when crate docs are involved)
  • CHANGELOG.md updated (if behavior changes are involved)