write-specs

star 3.9k

Write specifications. Always load this skill before writing to `specs`.

ethereum By ethereum schedule Updated 6/2/2026

name: write-specs description: >- Write specifications. Always load this skill before writing to specs. compatibility: Requires make and uv

Writing specifications

Building

The markdown files are automatically compiled into executable Python files when using the project's make rules. Run make help verbose=true for documentation on available rules. Generally, only the linting and testing rules are used.

Work-in-progress banners

Unstable specifications must include a work-in-progress banner at the top of the document, directly below the title. Remove the banner once the specification is promoted to the stable section of the project's README.

Table of contents

Do not manually edit the table of contents. Running make lint regenerates it automatically.

Code style

Simplicity is a guiding principle of the specs. Code should be concise and readable, and performant only where that does not sacrifice those qualities. Implementations will apply optimizations that the specs deliberately omit.

Strive to write code in a generic way that other languages can translate without difficulty. Avoid Python-specific functional helpers like map and filter. A list comprehension or an explicit loop expresses the same logic and maps more cleanly onto other languages.

Avoid single-letter variable names, except where a single letter is the conventional notation in a mathematical expression.

Add a comment only when the code alone would leave something important unclear to the reader. Do not restate what the code already does.

Docstrings and comments must be wrapped at 80 characters. In docstrings, inline code must use double backticks so it renders correctly in mkdocs. The linter does not enforce this, so it must be done manually. Only apply these rules to the docstrings and comments you add or change. Leave those outside the scope of your change untouched.

The specs make heavy use of SSZ types. Functions that operate on chain data should accept and return SSZ types, since the chain itself is stored entirely as SSZ types. Objects that are not part of the consensus data have no such requirement and may use ordinary Python types and dataclasses instead.

Asserts signal an impossible situation or something that is not allowed. Implementations are expected to handle these cases with proper error handling. Do not use assert messages.

Documenting changes

Changes in functionality between upgrades must be properly documented. Only document changes made directly to an item, not changes that ripple in from its dependencies. For example, if foo() calls bar() and bar() changes, foo() should not annotate that bar() changed.

Section prefixes

When an item such as a container or function has its own section, prefix the section name with "New" or "Modified" accordingly. Phase0 specifications do not use "New" prefixes, since everything there is considered new.

Annotations

Annotations such as # [New in Deneb] and # [Modified in Deneb] indicate that a line or block of code has changed, where the name is the upgrade that introduced the change. If a change is associated with a particular EIP, the comment must include its number, as in # [New in Deneb:EIP4844]. For multiple EIPs, list them like # [New in Deneb:EIP4844:EIP4788]. These must be standalone comments on their own line. Only "New" and "Modified" are allowed keywords. # [Removed in Deneb] is not allowed. Removed code within functions is not typically documented, but removed structure fields or function parameters are, as shown below:

# [Modified in Deneb]
# Removed `parameter`

If a function is refactored so heavily that annotations within the function body would be impractical, omit them and add a note instead.

Notes

Notes are paragraphs placed above a code block to give the reader insight that comments cannot. A note should not simply restate how the item now behaves, since that is clear from reading the item itself. Use a note only to call out a subtle change the reader might otherwise miss.

Deprecations

If an existing spec item is no longer needed in a newer spec, mark it as deprecated by adding its name to the deprecation list for that item's type in that spec's SpecBuilder class. Define a deprecation only in the spec where the item is first dropped. Later specs inherit it automatically.

Install via CLI
npx skills add https://github.com/ethereum/consensus-specs --skill write-specs
Repository Details
star Stars 3,939
call_split Forks 1,272
navigation Branch main
article Path SKILL.md
Occupations
More from Creator