```
---
name: spec-doc
description: Generate comprehensive input/output documentation for Ethereum consensus spec functions. Use when asked to document a function, analyze state access patterns, or create test documentation for spec functions. allowed-tools: Read, Grep, Glob, Write
---
```
# Ethereum Spec Function Documentation Generator
Generate comprehensive input/output space documentation for functions from the
Ethereum consensus layer specifications.
## Arguments
- Function name (required): e.g., `process_withdrawals`,
`get_expected_withdrawals`
- Fork name (optional): e.g., `gloas`, `electra`. Defaults to searching from
newest fork.
## Output Format
Generate a markdown document with these sections:
### 1. Header
```
# `<function_name>` Test Specification
*Note*: This report is AI-generated and is not an authoritative source of truth.
```
### 2. Function Signature
Show the Python signature from the spec with full type annotations.
### 3. Location
Link to the spec file where the function is defined.
### 4. Input Space Table
| Field | Type | Value Space | Purpose | Create a row for each state field READ
by the function:
- Field: Full path (e.g., `state.validators[*].effective_balance`)
- Type: SSZ type or custom type
- Value Space: Valid ranges, constraints, bounds (reference other fields if
applicable)
- Purpose: Why this field is read
For functions with operation inputs (e.g., `ProposerSlashing`, `DepositRequest`),
create a separate sub-table for the operation container fields.
See `.claude/mb/test_process_proposer_slashing.md` for an example with operation
input tables, and `.claude/mb/test_process_deposit_request.md` for routing logic.
### 5. Output Space Table
| Field | Type | Value Space | Modification | Create a row for each state field
MODIFIED by the function:
- Field: Full path
- Type: SSZ type
- Value Space: New value constraints
- Modification: How it changes (Set, Incremented, Decreased, Sliced, etc.)
### 6. Validation Conditions (if applicable)
For functions with `assert` statements, document all validation conditions that
cause the function to revert. List each condition with:
- The assertion being checked
- Why it's required
- What happens on failure
### 7. Early Exit Conditions
Document any conditions that cause early return with no modifications. Include
the condition and what triggers it.
### 8. Key Constants Table
| Constant | Value | Description | List all constants used by the function.
### 9. Key Cross-Field Constraints
Numbered list of invariants and relationships between fields.
### 10. Context-Specific Sections
Add explanatory sections for complex domain concepts. Examples:
- "Builder Model" for builder-related functions in gloas
- "GLOAS-Specific: <feature>" for fork-specific behavior
- "Difference from <previous_fork>" when the function is modified from an
earlier fork
- "Routing Logic" for functions with branching paths
- Code snippets showing key algorithms
### 11. Functions Called
Show the call tree hierarchy:
```
- function_name(state) — fork
- helper_function(state) — fork
- nested_helper() — fork
```
### 12. Container Definitions (if applicable)
For functions where understanding the container structure is essential, include
the relevant container definitions:
```python
class ContainerName(Container):
field1: Type1
field2: Type2
```
### 13. Test Coverage Summary
Document existing test coverage with tables:
| Test | Validity | Coverage |
| ---- | -------- | -------- |
| `test_basic` | Valid | Basic happy path |
| `test_invalid_*` | Invalid | Error condition |
Group tests by category (e.g., "Inherited from Phase0", "GLOAS-Specific").
### 14. Summary Diagram
ASCII art diagram showing:
- INPUT box with all read fields
- Processing box with key steps
- OUTPUT box with all modified fields
## Analysis Process
1. **Locate Function**: Search specs from newest fork (gloas → fulu → electra →
deneb → capella → bellatrix → altair → phase0) to find function definition
2. **Extract Signature**: Get full typed signature from the `def` line
3. **Identify State Access**:
- Look for `state.<field>` patterns
- Track reads vs writes (assignment targets)
- Note indexed access patterns like `state.validators[idx]`
- Follow function calls to identify transitive state access
4. **Resolve Types**:
- Find Container definitions in spec files
- Map custom types using "Custom types" tables
- Include List/Vector bounds
5. **Find Constants**:
- Extract SCREAMING_SNAKE_CASE identifiers
- Look up in Constants/Preset/Configuration sections
- Include max bounds, limits, and special values
6. **Build Call Tree**:
- Trace all function calls
- Note which fork each function is from
- Include helper functions
7. **Document Constraints**:
- Index alignment requirements
- Epoch/slot comparisons
- Balance thresholds
- Processing order and caps
## Output File Location
Write the documentation to a `.md` file. Two locations are supported:
### Default: Memory Bank
Place in the memory bank directory:
`.claude/mb/test_<function_name>.md`
This is the primary location for spec-docs because:
- Keeps documentation close to other working artifacts
- Supports iterative test development
- Quick reference during implementation
- Does not clutter the test directories
### Alternative: Test Directory (for finalized docs)
If the user explicitly requests, place alongside the test file:
`tests/core/pyspec/eth2spec/test/<fork>/<category>/test_<function_name>.md`
1. **Find existing test file**: Search for `test_<function_name>.py` to
determine the correct directory
2. **Infer from function name** if no test exists:
- Block processing: `process_attestation`, `process_withdrawals`,
`process_deposit`, etc.
- Epoch processing: `process_justification_and_finalization`,
`process_rewards_and_penalties`, etc.
- Fork choice: Functions in fork-choice.md
- Unittests: Helper functions like `get_*`, `is_*`, `compute_*`
**Directory mapping**:
| Pattern | Directory |
| ----------------- | ------------------- |
| Block `process_*` | `block_processing/` |
| Epoch `process_*` | `epoch_processing/` |
| Fork choice | `fork_choice/` |
| Finality | `finality/` |
| Rewards | `rewards/` |
| Helpers | `unittests/` |
| Sanity tests | `sanity/` |
## Step-by-Step Instructions
When the user invokes this skill with a function name:
01. **Parse Arguments**
- Extract function name from the argument
- Extract optional fork name if provided (e.g.,
`/spec-doc process_withdrawals gloas`)
02. **Search for Function Definition** Use Grep to find the function in spec
files:
```
Grep pattern: "^def <function_name>\(" in specs/**/*.md
```
Search order: gloas → fulu → electra → deneb → capella → bellatrix → altair
→ phase0
03. **Read the Function** Read the spec file containing the function definition.
Extract:
- Full function signature with types
- Complete function body
- Note the fork it's defined in
04. **Identify Called Functions** For each function called within the body:
- Search for its definition in spec files
- Note which fork it's from
- Recursively analyze state access
05. **Find Container Definitions** For types used (BeaconState, Validator,
etc.):
- Search for `class <Type>(Container):` in spec files
- Extract field names and types
06. **Lookup Constants** For SCREAMING_SNAKE_CASE identifiers:
- Search in Constants, Preset, and Configuration sections
- Note values and descriptions
07. **Build Input/Output Tables** Analyze function body:
- `state.field` on right side of `=` or in conditions → INPUT
- `state.field =` or `state.field[i] =` → OUTPUT
- Track through helper functions
08. **Determine Output Location** Search for existing test file:
```
Glob pattern: **/test_<function_name>.py
```
Use the directory where the test file is located, or infer from function
name pattern.
09. **Analyze Test Coverage** Read the existing test file to document:
- Test function names and what they cover
- Group by category (inherited, fork-specific, edge cases)
- Note valid vs invalid test cases
10. **Generate Documentation** Create markdown file with all sections following
the format in the examples.
11. **Write Output** Write to the appropriate location:
- Default: `.claude/mb/test_<function_name>.md`
- If user requests test directory: `tests/core/pyspec/eth2spec/test/<fork>/<category>/test_<function_name>.md`
## Example Reference
See these examples for the target format:
- `.claude/mb/test_process_proposer_slashing.md` - Shows validation conditions,
operation input tables, and GLOAS-specific sections
- `.claude/mb/test_process_deposit_request.md` - Shows routing logic, difference
from previous fork, and container definitions
- `tests/core/pyspec/eth2spec/test/gloas/block_processing/test_process_withdrawals.md` -
Shows complex processing with multiple withdrawal types
Key formatting elements:
- Tables use markdown pipe syntax with aligned columns
- Horizontal rules
(`______________________________________________________________________`)
separate major sections
- Code blocks use triple backticks with language hints
- Links use relative paths to spec files
- Cross-references use **bold** for emphasis on constraints
- The summary diagram uses ASCII box drawing
## Important Notes
- Always read the actual function code before generating documentation
- Follow function calls to capture transitive state access
- Include all fields accessed, even through helper functions
- Document epoch/slot boundaries and comparisons carefully
- Note index bounds and wrapping behavior
- Include builder-specific sections when relevant to gloas fork
- Use relative links to spec files from the output location
- Include Validation Conditions section for functions with assert statements
- Include Test Coverage Summary to document existing tests
- Include Container Definitions when they're central to understanding the function