Documentation
¶
Overview ¶
Package idea parses and represents SpecScore Idea artifacts.
An Idea is a single markdown file under `spec/ideas/` (or `spec/ideas/archived/`) that captures a pre-spec, lintable one-pager: problem framing, recommended direction, MVP scope, exclusions, and dealbreaker assumptions. See `spec/features/idea/README.md` for the full artifact schema.
This package provides parsing utilities — the lint rules that enforce the schema live in `pkg/lint`.
Index ¶
- Variables
- func FeatureSourceIdeas(specRoot string) (map[string][]string, error)
- func FindIdeaDirectories(specRoot string) ([]string, error)
- func Scaffold(opts ScaffoldOptions) ([]byte, error)
- func SortedStatuses() []string
- func ValidateSlug(slug string) error
- type Discovered
- type HeaderField
- type Idea
- type ScaffoldOptions
- type Section
- type Table
Constants ¶
This section is empty.
Variables ¶
var RequiredHeaderFields = []string{
"Status",
"Date",
"Owner",
"Promotes To",
"Supersedes",
"Related Ideas",
}
RequiredHeaderFields lists required **X:** fields in order.
var RequiredSections = []string{
"Problem Statement",
"Context",
"Recommended Direction",
"Alternatives Considered",
"MVP Scope",
"Not Doing (and Why)",
"Key Assumptions to Validate",
"SpecScore Integration",
"Open Questions",
}
RequiredSections names the sections that every Idea MUST have, in order.
var ValidRelationships = map[string]bool{ "depends_on": true, "alternative_to": true, "extends": true, "conflicts_with": true, }
Valid relationship types for Related Ideas entries.
var ValidStatuses = map[string]bool{ "Draft": true, "Under Review": true, "Approved": true, "Specified": true, "Archived": true, }
Valid statuses for an Idea.
Functions ¶
func FeatureSourceIdeas ¶
FeatureSourceIdeas scans every `spec/features/**/README.md` and returns a map of feature slug -> []idea-slug based on the **Source Ideas:** header. Features without the field are omitted. Only top-level feature dirs are returned (filepath suffix: "features/<slug>/README.md").
func FindIdeaDirectories ¶
FindIdeaDirectories returns directories that exist at `spec/ideas/<slug>/` (violation per REQ: single-file). Ignores the reserved `archived/` dir.
func Scaffold ¶
func Scaffold(opts ScaffoldOptions) ([]byte, error)
Scaffold returns a lint-clean Idea file body for the given options. Every required section is emitted either with an HTML-comment prompt (the default) or with the supplied content.
func SortedStatuses ¶
func SortedStatuses() []string
Sort returns a slice of statuses sorted alphabetically (helper for tests).
func ValidateSlug ¶
ValidateSlug returns nil if slug matches `[a-z0-9]+(-[a-z0-9]+)*`.
Types ¶
type Discovered ¶
type Discovered struct {
Slug string
Path string // absolute or relative path to the .md file
Archived bool // true if located under archived/
}
Discovered is a summary of an Idea file found during discovery.
func Discover ¶
func Discover(specRoot string) ([]Discovered, error)
Discover walks `<specRoot>/ideas` and returns every idea file found. Returns ([], nil) if the directory does not exist.
type HeaderField ¶
HeaderField captures a single **Name:** value line.
type Idea ¶
type Idea struct {
Path string
Slug string
Title string // full title line (without leading "# ")
TitleName string // name portion after "Idea: "
TitleOK bool // true if title matches "# Idea: <Name>"
TitleLine int
HasTitle bool
Fields []HeaderField // in-order header fields encountered
FieldByName map[string]HeaderField
Sections []Section
SectionByTitle map[string]*Section
RawLines []string
}
Idea is a parsed Idea artifact.
func Parse ¶
Parse reads an Idea file and returns its parsed representation. Parse is resilient — it returns a partial Idea even if the file is malformed (missing title, missing sections). Callers (lint rules) decide what is an error.
func (*Idea) ArchiveReason ¶
ArchiveReason returns the Archive Reason value or "".
func (*Idea) PromotesTo ¶
PromotesTo returns the parsed Promotes To slugs (comma-separated list). A value of "—" or "-" means empty.
func (*Idea) RelatedIdeas ¶
RelatedIdeas returns the raw entries (un-split) from the Related Ideas field.
func (*Idea) Supersedes ¶
Supersedes returns the parsed Supersedes slugs.
type ScaffoldOptions ¶
type ScaffoldOptions struct {
Slug string
// Title is the human-readable name after `# Idea: `. Defaults to
// a title-cased version of the slug.
Title string
Owner string
// Date in ISO-8601 (YYYY-MM-DD). Defaults to today's UTC date.
Date string
// Status defaults to "Draft".
Status string
// Section content. Empty strings leave the default prompt in place.
HMW string // Problem Statement
Context string
RecommendedDirection string
Alternatives []string // Each element is a bullet for Alternatives Considered.
MVP string
// NotDoing is a list of exclusions. When empty, a lint-clean default
// list is emitted so the Not Doing section passes idea-not-doing-non-empty.
NotDoing []string
// Assumptions is an optional list of assumption-table rows.
// Each row is {Tier, Assumption, HowToValidate}. When empty, a
// lint-clean default table with one Must-be-true row is emitted.
Assumptions [][3]string
// SpecScore Integration overrides.
NewFeatures string
Existing string
Dependencies string
// OpenQuestions bullets (optional).
OpenQuestions []string
}
ScaffoldOptions controls the content emitted by Scaffold. Any field left empty keeps the section's default HTML-comment prompt.
type Section ¶
type Section struct {
Title string
StartLine int
EndLine int
Body string
Items []string // lines starting with "- "
}
Section captures a single ## heading and its body.
type Table ¶
Table captures a markdown pipe-table within a section.
func ParseTable ¶
ParseTable extracts a markdown pipe-table from the given section body. Returns nil if no table is present. Only the first table is returned.