The M21 Spec Format
A spec combines machine-readable data models and semantic interfaces with architectural prose and executable behavioral features.
Anatomy of a spec file
The ordered contract stack
- Data model — entities, fields, relationships, states, and structural constraints.
- Interfaces — operations, inputs, outputs, failures, effects, and events.
- Contract — responsibilities, non-goals, invariants, dependencies, and decisions.
- Features — executable examples of observable behavior.
Sections are optional when irrelevant, but present sections follow this order. Use fenced m21-model and m21-interface YAML blocks for declarations that M21 must enforce.
Supported structural field types
string, number, integer, boolean, object, array, enum, and reference. Local references use an entity name; cross-spec references use spec-name.Entity and require a declared dependency.
m21 validate ./spec checks block syntax, identifiers, field types, entity references, and cross-spec model dependencies. m21 model ./spec --json exports the normalized registry; m21 schema ./spec emits JSON Schema.
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 provide executable examples of semantic interfaces and guarantees. Other specs use feature names as behavioral capability identifiers through 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 owns models and semantic interfaces, then demonstrates behavior through
.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.