Documentation
¶
Overview ¶
Package ears implements the semantic pillar: classification and linting of requirements written in EARS (Easy Approach to Requirements Syntax).
Every rule in a spectackle spec file must match exactly one of the six EARS patterns. Vague prose is rejected by the linter; keywords are case-sensitive and uppercase (WHEN, WHILE, IF, THEN, WHERE, SHALL) so that lowercase occurrences in code fragments (e.g. "if (i < n)") never trigger a pattern.
Index ¶
- func Compose(p Pattern, s Slots) (string, error)
- func FrontMatter(s string) string
- func IsProseSection(name string) bool
- func MissingSlots(p Pattern, s Slots) []string
- func ParseRules(text, file string, startLine int) ([]Rule, []Finding)
- func StripFrontMatter(s string) (body string, bodyStartLine int)
- type Finding
- type Pattern
- type Rule
- type Section
- type Severity
- type Slots
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Compose ¶
Compose builds the canonical EARS sentence for pattern p from slots. Clause order for Complex follows the EARS convention: WHERE, WHILE, WHEN/IF, response.
func FrontMatter ¶
FrontMatter returns the raw YAML between the fences, or "".
func IsProseSection ¶
IsProseSection reports whether a heading name is a whitelisted prose section.
func MissingSlots ¶
MissingSlots returns the slot names still required to compose a rule of pattern p. An empty result means Compose will succeed.
func ParseRules ¶
ParseRules extracts rules from spec-file markdown (front matter already stripped by the caller, or absent). startLine is the 1-based line number of the first line of text within the original file. It reports structural findings (E005) alongside the parsed rules.
func StripFrontMatter ¶
StripFrontMatter removes a leading "---\n...\n---\n" YAML block and returns the remaining body plus the 1-based line number the body starts at.
Types ¶
type Finding ¶
Finding is one lint result, renderable as "! <code> <sev> <file>:<line> <msg>".
func LintFile ¶
LintFile parses and lints one spec file from disk (including front matter stripping identical to the cascade loader).
func LintSentence ¶
LintSentence checks a single rule sentence (codes E001-E004, W001-W002).
type Pattern ¶
type Pattern uint8
Pattern is one of the six EARS rule patterns.
const ( PInvalid Pattern = iota PUbiquitous // The <system> SHALL <response>. PEvent // WHEN <trigger>, the <system> SHALL <response>. PState // WHILE <state>, the <system> SHALL <response>. PUnwanted // IF <condition>, THEN the <system> SHALL <response>. POptional // WHERE <feature>, the <system> SHALL <response>. PComplex // combination, e.g. WHERE ..., WHEN ..., the <system> SHALL ... )
func Classify ¶
Classify returns the EARS pattern of a normalized rule sentence, or PInvalid if it matches none.
func PatternFromString ¶
PatternFromString maps the one-letter tool encoding to a Pattern.
type Rule ¶
type Rule struct {
ID string
Pattern Pattern
Text string // the EARS sentence
Rationale string // optional "Rationale:" paragraph
Applies []string // optional node IDs from "{applies: id,id}" heading suffix
File string
Line int // line of the "## <ID>" heading
}
Rule is one parsed spec rule (heading + sentence) inside a spec file.
type Section ¶
type Section struct {
Name string
Line int // 1-based heading line within the given text
Text string
}
Section is one prose section of a spec file.
func ParseSections ¶
ParseSections extracts the whitelisted prose sections from spec-file markdown (front matter already stripped).
type Slots ¶
type Slots struct {
System string // "the <system>" subject; leading "the " is stripped
Response string // what the system SHALL do (must name something verifiable)
Trigger string // WHEN … (Event-driven, Complex)
State string // WHILE … (State-driven, Complex)
Condition string // IF … (Unwanted behaviour, Complex)
Feature string // WHERE … (Optional feature, Complex)
}
Slots are the structured inputs a rule is composed from. End users and agents never hand-write EARS sentences; they fill slots (via the add_rule MCP tool, elicitation-guided) and the server composes and lints the sentence deterministically.