The modspec Spec Format
A spec is a markdown file with YAML frontmatter. It's the source of truth for your project's module structure, dependencies, and feature contracts.
Anatomy of a spec file
Frontmatter fields
| Field | Required | Type | Description |
|---|---|---|---|
name |
Yes | string |
Unique identifier. How other specs reference it in depends_on. |
description |
No | string |
Short summary. Shown in the graph info panel. |
group |
No | string |
Logical grouping. Specs in the same group are visually clustered. |
tags |
No | string[] |
Tags for filtering and categorization. |
depends_on |
No | array |
Dependencies. Supports plain strings or {name, uses} objects. |
features |
No | string |
Relative path to a directory of .feature files. |
Dependencies
The depends_on field supports two formats that can be mixed freely:
Simple format
Rich format (with feature references)
The uses array references Feature: names declared in the parent spec's .feature files. This creates a traceable contract — you know exactly which capabilities each module relies on.
Feature files
Features are defined in Gherkin .feature files. They serve as the public interface of a spec — other specs declare which features they depend on via uses.
Naming rules
- Feature names must be kebab-case:
Feature: data-storage - File names should match:
data-storage.feature - The
usesreferences must match theFeature:name exactly
Example feature file
Groups
Specs with the same group value are visually clustered in the graph with a colored hull behind them. Use groups to organize by architectural layer or domain:
foundation— bootstrap, config, shared utilitiesinfrastructure— database, caching, messagingdomain— core business logicapi— HTTP endpoints, GraphQLui— frontend components
Composability
Specs are designed as composable modules. The dependency graph captures not just what depends on what, but which features each module needs from its dependencies.
- Provider spec declares features via
.featurefiles - Consumer spec declares which features it needs via
uses - The graph visualizes these contracts as labeled edges
This makes it clear when a dependency change might break downstream consumers — you can see exactly which features are in use.