ought-spec
Parser and clause IR for the .ought.md spec format.
This crate defines the open standard for ought specs: the grammar (see
docs/grammar.md), the parsed data types, and the walker that turns a
directory tree of spec files into a queryable graph. It has zero LLM
dependencies — any tool can consume specs by depending on this crate alone.
Responsibilities
- Parse
.ought.mdfiles into structuredSpec/Section/Clausevalues. - Compute stable clause IDs and content hashes used by the rest of the stack.
- Walk a set of roots and build a
SpecGraphwith cross-file references resolved. - Own
SpecsConfig— the[specs]section ofought.toml(spec roots), since spec discovery is this crate's concern.
Notable public API
trait Parser— the public interface for parsing. Methods:parse_file(&self, path)(with a default impl that reads the file and delegates toparse_string),parse_string(&self, content, path), andname(&self). Most consumers should take&dyn Parser(orimpl Parser) rather than a concrete type.OughtMdParser— the canonical implementation for.ought.mdfiles. Zero-state unit struct, soOughtMdParser.parse_file(&path)is the usual call pattern. Pure Rust, no LLM dependency.SpecGraph::from_roots(&roots)— convenience that parses every spec under a set of roots with the defaultOughtMdParser.SpecGraph::from_roots_with(&dyn Parser, &roots)— inject a custom parser; useful for tests and for future alternate spec formats.- Types:
Spec,Section,Clause,ClauseId,Keyword,Severity,Temporal,SourceLocation,Metadata,SpecRef,ParseError. SpecsConfig { roots }— deserializable sub-config composed by the aggregateConfiginought-cli.