projectdef

package
v0.14.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 18, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

pkg/projectdef

specscore.yaml schema and read/write operations per the Repo Config feature. Validates the mandatory schema-header comment on line 1, applies SpecStudio defaults for viewer:, and enforces module path uniqueness/non-nesting.

Outstanding Questions

None at this time.

Documentation

Overview

Package projectdef provides the specscore.yaml schema and read/write operations defined by the SpecScore Repo Config feature (https://specscore.md/repo-config).

Index

Constants

View Source
const (
	DefaultSpecsDirName = "specs"
	DefaultDocsDirName  = "docs"
	DefaultStudioName   = "SpecScore.Studio"
	DefaultStudioURL    = "https://specscore.studio/"
	DefaultModuleName   = "default"
	// DefaultIdeasPath is the module-relative ideas directory used when a
	// module declares no path_overrides.ideas_path
	// (configurable-ideas-path#req:ideas-path-default).
	DefaultIdeasPath = "spec/ideas"
)

Default values supplied when fields are omitted.

View Source
const SchemaHeader = "# SpecScore Repo Config Schema: https://specscore.md/repo-config"

SchemaHeader is the exact comment that MUST appear on line 1 of every specscore.yaml file. See repo-config#req:schema-header-comment.

View Source
const SpecConfigFile = "specscore.yaml"

SpecConfigFile is the canonical filename for the repo-level config, per the repo-config feature.

Variables

View Source
var DefaultGradeValues = []string{"A", "B", "C", "D", "F"}

DefaultGradeValues is the built-in grade value set applied when no `grade.values` is configured (canonical-grade-metadata-field#req:grade-values-default).

Functions

func IsValidRole

func IsValidRole(r Role) bool

IsValidRole reports whether r is a member of the canonical role enum.

func ValidateSchemaHeader

func ValidateSchemaHeader(data []byte) error

ValidateSchemaHeader verifies the first line of `data` is exactly the schema-header comment. Returns nil on success.

func WriteSpecConfig

func WriteSpecConfig(dir string, cfg SpecConfig) error

WriteSpecConfig serializes cfg to dir/specscore.yaml, prepending the schema-header comment as line 1.

Types

type GradeConfig added in v0.5.1

type GradeConfig struct {
	Values []string
	// contains filtered or unexported fields
}

GradeConfig is the optional `grade:` block. It carries the repository's allowed `**Grade:**` value set (canonical-grade-metadata-field#req:grade-values-config).

Shape problems (a scalar `values`, an empty list, a non-scalar or empty entry, or a non-mapping `grade`) are recorded in shapeErr rather than returned as an unmarshal error, so a malformed block surfaces as a single `grade-values-shape` lint violation instead of breaking every config read.

func (*GradeConfig) UnmarshalYAML added in v0.5.1

func (g *GradeConfig) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML parses the `grade:` mapping, validating the shape of `values` per canonical-grade-metadata-field#req:grade-values-shape. It never returns an error for shape problems; it records shapeErr.

type ModuleConfig

type ModuleConfig struct {
	Name          string         `yaml:"name,omitempty"`
	Path          string         `yaml:"path,omitempty"`
	Code          []string       `yaml:"code,omitempty"`
	PathOverrides *PathOverrides `yaml:"path_overrides,omitempty"`
	Extras        map[string]any `yaml:",inline"`
}

ModuleConfig is one entry in the `modules:` list — a code area inside the repo, optionally with its own specs/docs subdirectories.

func (ModuleConfig) EffectiveIdeasPath added in v0.9.0

func (m ModuleConfig) EffectiveIdeasPath() string

EffectiveIdeasPath returns the module-relative ideas directory: path_overrides.ideas_path when set, else the default "spec/ideas" (configurable-ideas-path#req:ideas-path-default, configurable-ideas-path#req:ideas-path-override). The result is relative to the module root; join with the module's EffectivePath for a repo-relative location.

func (ModuleConfig) EffectiveName

func (m ModuleConfig) EffectiveName() string

EffectiveName returns the module's effective name per repo-config#req:module-name-deduction.

func (ModuleConfig) EffectivePath

func (m ModuleConfig) EffectivePath() string

EffectivePath returns the module's effective filesystem path, defaulting to "." (repo root) when no path is set.

func (ModuleConfig) EffectiveSeedsPath added in v0.9.0

func (m ModuleConfig) EffectiveSeedsPath() string

EffectiveSeedsPath returns the module-relative sidekick-seed directory, which is always "seeds" under the resolved ideas directory (configurable-ideas-path#req:seeds-follow-ideas).

type PathOverrides added in v0.9.0

type PathOverrides struct {
	IdeasPath string         `yaml:"ideas_path,omitempty"`
	Extras    map[string]any `yaml:",inline"`
}

PathOverrides holds per-module, per-artifact-kind directory overrides (repo-config#req:path-overrides-optional). Only IdeasPath is interpreted in v1; any other key round-trips unchanged via Extras.

type ProjectConfig

type ProjectConfig struct {
	Title        string             `yaml:"title,omitempty"`
	Host         string             `yaml:"host,omitempty"`
	Org          string             `yaml:"org,omitempty"`
	Repo         string             `yaml:"repo,omitempty"`
	Repositories []RepositoryConfig `yaml:"repositories,omitempty"`
	Extras       map[string]any     `yaml:",inline"`
}

ProjectConfig holds project identity. All fields are optional; when omitted, callers infer values from the working directory and git remote.

type PromoteConfig added in v0.6.1

type PromoteConfig struct {
	// VerdictCarryForward sets the project-default verdict carry-forward
	// mode (pointer | full | drop). Empty/absent means the verb falls back
	// to its built-in default. A `--verdict` flag overrides this.
	VerdictCarryForward string         `yaml:"verdict_carry_forward,omitempty"`
	Extras              map[string]any `yaml:",inline"`
}

PromoteConfig is the optional `promote:` block. It configures the `specscore idea promote` verb's project defaults. See spec/features/cli/idea/promote/README.md#req:verdict-carry-forward.

type RepositoryConfig

type RepositoryConfig struct {
	URL     string         `yaml:"url"`
	Title   string         `yaml:"title,omitempty"`
	Comment string         `yaml:"comment,omitempty"`
	Roles   []Role         `yaml:"roles"`
	Extras  map[string]any `yaml:",inline"`
}

RepositoryConfig is one entry in `project.repositories`. Per repo-config#req:repositories-entry-shape every entry MUST be a YAML mapping (object) with a non-empty `roles` list — flat URL strings are rejected.

func (*RepositoryConfig) UnmarshalYAML

func (r *RepositoryConfig) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML enforces repo-config#req:repositories-entry-shape — the entry MUST be a mapping (not a scalar / not a sequence). Flat URL strings are rejected with a hard error citing the violated REQ.

type Role

type Role string

Role is a value from the closed enum defined in repo-config#req:repositories-roles-enum.

const (
	RoleCode          Role = "code"
	RoleSpecification Role = "specification"
	RoleState         Role = "state"
	RoleDocs          Role = "docs"
	RoleRunner        Role = "runner"
)

Canonical role values per repo-config#req:repositories-roles-enum. The enum is closed in v1; new values require a Feature revision.

type SpecConfig

type SpecConfig struct {
	Project      *ProjectConfig `yaml:"project,omitempty"`
	Projects     []string       `yaml:"projects,omitempty"`
	SpecsDirName string         `yaml:"specs_dir_name,omitempty"`
	DocsDirName  string         `yaml:"docs_dir_name,omitempty"`
	Studio       *StudioConfig  `yaml:"studio,omitempty"`
	Modules      []ModuleConfig `yaml:"modules,omitempty"`
	Grade        *GradeConfig   `yaml:"grade,omitempty"`
	Promote      *PromoteConfig `yaml:"promote,omitempty"`
	Extras       map[string]any `yaml:",inline"`
	// contains filtered or unexported fields
}

SpecConfig is the deserialized form of specscore.yaml.

func ReadSpecConfig

func ReadSpecConfig(dir string) (SpecConfig, error)

ReadSpecConfig reads dir/specscore.yaml and decodes it. The file must begin with the schema-header comment on line 1; otherwise an error is returned without further parsing.

The pre-2026-05-19 `viewer:` block is rejected with a migration error (repo-config#req:viewer-block-rejected). It MUST be hand-renamed to `studio:` — there is no auto-migration in this pre-v1 break.

func (SpecConfig) EffectiveDocsDirName

func (c SpecConfig) EffectiveDocsDirName() string

EffectiveDocsDirName returns the configured docs dir name or the default.

func (SpecConfig) EffectiveGradeValues added in v0.5.1

func (c SpecConfig) EffectiveGradeValues() []string

EffectiveGradeValues returns the repository's allowed grade value set: the configured `grade.values` (de-duplicated) when present and non-empty, otherwise DefaultGradeValues (canonical-grade-metadata-field#req:grade-values-default).

func (SpecConfig) EffectiveModules

func (c SpecConfig) EffectiveModules() []ModuleConfig

EffectiveModules returns the module list with the implicit-root default applied per repo-config#req:modules-default.

func (SpecConfig) EffectiveSpecsDirName

func (c SpecConfig) EffectiveSpecsDirName() string

EffectiveSpecsDirName returns the configured specs dir name or the default.

func (SpecConfig) EffectiveStudio

func (c SpecConfig) EffectiveStudio() (name, url string, suppressed bool)

EffectiveStudio reports the studio to use for artifact links. suppressed is true when `studio: null` was set explicitly — callers MUST omit any toolbar in that case (repo-config#req:studio-null-opts-out). When the block is omitted entirely, name and url default to SpecScore.Studio (repo-config#req:studio-default-when-omitted).

func (SpecConfig) GradeShapeError added in v0.5.1

func (c SpecConfig) GradeShapeError() string

GradeShapeError returns the recorded `grade.values` shape error, or "" when the block is absent or well-formed.

func (SpecConfig) GradeValuesHasDuplicates added in v0.5.1

func (c SpecConfig) GradeValuesHasDuplicates() bool

GradeValuesHasDuplicates reports whether the configured `grade.values` list contains duplicate tokens (a lint advisory, not a hard error).

func (SpecConfig) IsStudioSuppressed

func (c SpecConfig) IsStudioSuppressed() bool

IsStudioSuppressed reports whether studio: null was set in the source.

func (SpecConfig) Validate

func (c SpecConfig) Validate() error

Validate checks the structural invariants that don't require I/O: studio mapping completeness, repositories entry shape and role-enum membership, and module path uniqueness/non-nesting. File-system checks (e.g. projects local-path resolution) belong to the linter.

type StudioConfig

type StudioConfig struct {
	Name string `yaml:"name"`
	URL  string `yaml:"url"`
}

StudioConfig names the upstream studio that renders SpecScore artifacts. Both fields are required when the block is present. Replaces the pre-2026-05-19 `viewer:` block (repo-config#req:studio-explicit-values).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL