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

---
name: persistence
description: SQLite database layer for local storage
group: infrastructure
tags: [database, storage]
depends_on:
  - name: bootstrap
    uses: [project-scaffolding, health-endpoint]
features: features/persistence/
---

# Persistence

Handles the database abstraction layer.
Uses SQLite for local-first storage.

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

depends_on:
  - bootstrap
  - config

Rich format (with feature references)

depends_on:
  - name: bootstrap
    uses: [project-scaffolding, health-endpoint]
  - name: persistence
    uses: [data-storage, query-interface]

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

Example feature file

Feature: data-storage
  CRUD operations for persistent entities.

  Scenario: Store and retrieve an entity
    Given an empty data store
    When I store entity "foo" with value "bar"
    Then retrieving "foo" returns "bar"

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:

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.

  1. Provider spec declares features via .feature files
  2. Consumer spec declares which features it needs via uses
  3. 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.

Example project

# spec/bootstrap.md
name: bootstrap   group: foundation
features: features/bootstrap/

# spec/persistence.md
name: persistence   group: infrastructure
depends_on: [{name: bootstrap, uses: [project-scaffolding]}]
features: features/persistence/

# spec/auth.md
name: auth   group: infrastructure
depends_on: [{name: bootstrap, uses: [health-endpoint]}]
features: features/auth/

# spec/repos.md
name: repos   group: data
depends_on:
  - {name: persistence, uses: [data-storage, query-interface]}
  - {name: auth, uses: [user-login]}