specre
Atomic, living specification cards for AI-agent-friendly development.
specre ( /spékré/ ) is a minimal specification format and toolkit for Spec-Driven Development (SDD). Each specre is a single Markdown file describing exactly one behavior, with machine-readable front-matter for lifecycle tracking and agent navigation.
The Problem
Specifications are essential for keeping development intent visible and traceable. But in practice, they rot:
- Specs drift from code in silence. No one notices when an implementation diverges from its specification — until the next developer (or AI agent) builds on stale assumptions.
- Monolithic specs waste AI context. Large specification documents force agents to parse entire features just to understand a single behavior, consuming the finite context window that should be reserved for code and tests.
- Small changes never get specced. When the cost of writing a specification is high, only greenfield features get documented. Bug fixes, refactors, and incremental changes slip through unspecified.
specre exists to make specifications so small and so cheap to write that there is no reason to skip them.
Philosophy
Most SDD tools (GitHub Spec Kit, Amazon Kiro, BMAD) treat specifications as large, monolithic documents that feed into linear pipelines. specre takes the opposite approach:
- One file, one behavior. Keep the unit of specification atomic. An AI agent should never need to parse an entire feature to understand a single behavior.
- Context-window aware. LLM context is a finite resource. A specre is sized to fit comfortably alongside its test file and implementation in a single agent session.
- Living documents, not session artifacts. Each specre carries its own lifecycle status and verification date. Specifications survive beyond the task that created them.
- Process-agnostic data layer. specre defines the format of specifications, not the workflow. Use it with TDD, BDD, or any development process. Pair it with your own workflow commands or CI pipelines.
- Engine and tool independent. Plain Markdown with YAML front-matter. No IDE lock-in, no proprietary CLI required.
Quick Start
Install Pre-built Binary
# Linux / macOS
|
# Windows (PowerShell)
Install via Cargo (Rust users)
This installs the specre CLI from crates.io. Requires Rust 1.85+.
As a Git Submodule
Writing Your First specre
Create a Markdown file under your project's specres directory. Organize subdirectories however you like — by domain, module, feature area, or any scheme that fits your project:
docs/specres/
auth/
signup/
user_can_sign_up_with_email.md
system_sends_verification_email_on_signup.md
password/
user_can_reset_password.md
cart/
user_can_add_item_to_cart.md
cart_total_reflects_quantity_changes.md
Subdirectories within a domain are optional — use them when related behaviors benefit from grouping, but keep the tree flat where a single level is sufficient.
specre Card Format
Every specre follows this structure:
---
id: "01HZYPMZRK8F9R2DGBGGMM2N8T"
name: "user_can_sign_up_with_email"
status: "draft"
---
- --
Users can create an account by providing a valid email address and password.
Email signup is the primary onboarding path. We validate email format
client-side and uniqueness server-side to provide fast feedback.
- -
1. 2.3.
1. 2.3.
1. 2.
-
Front-Matter Fields
| Field | Type | Required | Description |
|---|---|---|---|
id |
ULID | Yes | Universally unique identifier in ULID format. The single key for bidirectional traceability between specres and source code. |
name |
string | Yes | Matches the filename (without .md). A sentence with a clear subject and predicate that describes the behavior (e.g., user_can_sign_up_with_email, system_rejects_invalid_email). Avoid function-style nouns like create_quotation. |
status |
enum | Yes | draft · in-development · stable · deprecated |
last_verified |
date | No | YYYY-MM-DD — when this specre was last confirmed to match the implementation. Applicable to stable specres. Not required for draft or in-development. |
Status Lifecycle
draft ──→ in-development ──→ stable ──→ deprecated
↑ │ │
└────────────┘ │
(requirements changed) │
↓
(superseded or removed)
- draft: Behavior is proposed but not yet implemented.
- in-development: Implementation or tests are in progress.
- stable: Implementation matches the specre. Tests pass. Verified by
last_verifieddate. - deprecated: Behavior has been removed or superseded. Kept for historical reference.
Status records the current state of a specre, not a prescribed workflow. Projects may skip states, move backwards, or adopt only a subset — specre does not enforce transitions.
Recommended Sections
| Section | Required | Purpose |
|---|---|---|
| Related Files | Yes | Links specre to source and test files by path (human-readable) |
| Functional Overview | Yes | One-paragraph summary of the behavior |
| Design Intent | No | Explains why, not what |
| Key Members | No | Important state and parameters in natural language |
| Scenarios | Yes | Step-by-step behavior descriptions |
| Failures / Exceptions | No | Edge cases and error handling |
Naming Conventions
- Name as a sentence. Every specre name must have a clear subject and predicate describing the behavior:
user_can_reset_password,system_rejects_expired_token,cart_total_reflects_quantity_changes. Avoid function-style nouns likecreate_quotationorpassword_reset. - No sequential numbering. Do not prefix filenames with
001_,002_, etc. The specre's ULID already provides chronological ordering. Sequential numbers create management overhead and friction with AI agents. - Use subdirectories for grouping. When a domain contains many related behaviors, group them with subdirectories instead of numbering. Prefer
quotation/approval/manager_can_approve_quotation.mdoverquotation/201_manager_can_approve_quotation.md. Keep the tree flat where a single level is sufficient.
Writing Guidelines
- Write scenarios in natural language, not code. Avoid copy-pasting implementation details.
- Do use exact names for signals, classes, and enums — these are the contract between spec and code.
- Keep each specre focused on a single behavior. If you find yourself writing "also, ..." — split it into a separate specre.
- specres can reference each other via relative paths in a "Referenced Specifications" section.
Bidirectional Traceability
specre uses a single ULID — the specre's id — to link specifications and source code in both directions. No intermediate tag layer is needed.
How It Works
┌─────────────────────────────┐
│ specre file (.md) │ ← Source of truth
│ ┌────────────────────────┐ │
│ │ id: ULID │ │
│ │ name / status │ │
│ │ last_verified │ │
│ └────────────────────────┘ │
│ ## Related Files │ ← Path-based reference (human-readable)
│ ## Scenarios │
└──────────────┬──────────────┘
│ id (ULID)
▼
┌──────────────────────────────┐
│ source file │
│ // @specre <ULID> │ ← Reverse reference (machine-readable)
└──────────────┬───────────────┘
│
▼
┌──────────────────────────────┐
│ index.json │ ← Generated cache (CLI-managed)
│ specres[]: front-matter │
│ source_refs[]: marker index │
└──────────────────────────────┘
- specre → Source: The "Related Files" section lists file paths. Human-readable, always up to date with the specre.
- Source → specre: A
@specremarker in a source comment references the specre'sid. Machine-readable, scannable by CLI. - index.json: A derived artifact generated by
specre index. Can be regenerated at any time. Never edit manually.
Source File Markers
Place a @specre marker in a comment to link a source file back to its specre:
# @specre 01HZYPMZRK8F9R2DGBGGMM2N8T
# ...
end
A file may reference multiple specres:
# @specre 01HZYPMZRK8F9R2DGBGGMM2N8T
# @specre 01HZYQ4N7XW3A8B5C6D9E0F1G2
...
The marker can be placed at the top of a file, above a class or function definition, or at the end — wherever it best communicates the relationship. The CLI detects markers by scanning for the pattern @specre [0-9A-Z]{26}, ignoring comment syntax.
Marker syntax by language:
| Language | Marker |
|---|---|
| Ruby / Python / GDScript / Shell | # @specre 01HZYPM... |
| JavaScript / TypeScript / Java / C# / C++ | // @specre 01HZYPM... |
| HTML / XML | <!-- @specre 01HZYPM... --> |
| CSS | /* @specre 01HZYPM... */ |
| SQL | -- @specre 01HZYPM... |
Why ULID?
ULID (Universally Unique Lexicographically Sortable Identifier) was chosen over UUID or sequential IDs because:
- Sortable by creation time: specres created earlier sort first, providing a natural chronological order without relying on filenames.
- No coordination required: ULIDs can be generated independently by any developer or agent without a central registry.
- Compact: 26 characters (vs. 36 for UUID), reducing noise in source comments.
- Monotonic within a millisecond: Multiple specres created in rapid succession maintain order.
Index Format
specre index scans the specification directory and source tree to generate index.json — a machine-readable cache for fast lookups.
specres Array
Each entry mirrors the front-matter of a specre file, with two derived fields:
| Field | Source | Description |
|---|---|---|
id |
front-matter | The specre's ULID |
name |
front-matter | Human-readable title |
status |
front-matter | Current lifecycle status |
domain |
directory name | Extracted from the top-level directory under the specres root (e.g., docs/specres/quotation/creation/foo.md → "quotation"). Subdirectories within a domain do not affect the domain value. |
path |
file system | Relative path from project root to the specre file |
last_verified |
front-matter | Date of last verification |
source_refs Array
Each entry records a @specre marker found in the source tree:
| Field | Description |
|---|---|
specre_id |
The ULID referenced by the marker |
file |
Relative path to the source file |
line |
Line number where the marker was found |
Design Principles
- index.json is a cache, not a source of truth. If it's missing or stale, run
specre indexto regenerate. Never edit it manually. - specre files are the source of truth. All authoritative data lives in the front-matter and body of each
.mdfile. - Per-directory INDEX.md can also be generated for human browsing — a Markdown table summarizing all specres in a subdirectory.
Comparison with Other Tools
| specre | Plain Markdown | GitHub Spec Kit | Amazon Kiro | Gherkin | |
|---|---|---|---|---|---|
| Granularity | One behavior | Varies | One feature | One feature | One feature (multi-scenario) |
| Unique ID | ULID per specre | None | None | None | None |
| Lifecycle status | Yes (4 states) | None | No | No | No |
| Verification date | Yes | None | No | No | No |
| Code traceability | Bidirectional (ULID) | None | None | None | Step definitions |
| Test integration | By convention | None | Optional | Optional | Executable |
| Process coupling | None | None | Linear pipeline | Linear pipeline | Test runner |
| Files per spec | 1 | Varies | 3-4 | 3 | 1 |
| IDE dependency | None | None | None | Kiro IDE | None |
| Index generation | CLI (JSON + Markdown) | None | None | Built-in | None |
Roadmap
Full details: docs/project/ROADMAP.md
- v0.1 — Core CLI ✅
init,new,index,status - v0.2 — Traceability ✅
trace,orphans,tag - v0.3 — Agent Integration —
coverage,health-check, MCP server,search,--jsonoutput - v0.4 — Drift Detection —
drift,ci, GitHub Actions template - v0.5 — QA Support —
impact,diff,export
Contributing
specre is in its early stages. Contributions, feedback, and real-world usage reports are welcome. Please open an issue or pull request on GitHub.
License
MIT
Atomic, living specification cards for AI-agent-friendly development. Minimal, agnostic, and traceable.