config

package
v0.50.0 Latest Latest
Warning

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

Go to latest
Published: Sep 11, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package config resolves SpecScore configuration from layered sources.

Configuration is read from four layers, in decreasing specificity:

specscore.local.yaml  (repo root, uncommitted)  -- most specific
specscore.yaml        (repo root, committed)
<owner>/.specscore.yaml (organization)
~/.specscore.yaml     (user home)               -- least specific

The most specific layer wins per key; mapping nodes are deep-merged, while scalars and sequences are replaced wholesale. An explicit null in a more specific layer clears a value set by a less specific one.

Index

Constants

View Source
const (
	ProjectFile = "specscore.yaml"
	LocalFile   = "specscore.local.yaml"
	HomeFile    = ".specscore.yaml"
)

Layer file names.

View Source
const LifecycleProjectLockIgnorePattern = ".specscore-lifecycle.lock"

LifecycleProjectLockIgnorePattern keeps the stable cross-process lifecycle fence out of source control. It is intentionally retained after a clean release so an interrupted process can be distinguished from a missing lock identity without relying on pathname creation races.

View Source
const LifecycleTransactionLockIgnorePattern = "**/.*.lifecycle-transaction.lock"

LifecycleTransactionLockIgnorePattern keeps crash-leftover flock identity files out of source control. Clean transactions remove their per-artifact lock after the stable project lock has serialized cleanup; an interrupted process can still leave one behind for the next run to reclaim safely.

Variables

View Source
var UserScopedKeys = []string{
	"recaps.repo",
	"recaps.user",
	"journal.repo",
	"journal.stream",
	"repo_checkouts",
}

UserScopedKeys are dotted config keys that carry per-user or per-machine values (filesystem paths, identities). They MUST NOT appear in the committed project file (specscore.yaml); they are accepted only from specscore.local.yaml or ~/.specscore.yaml. Owning Features register their keys here.

Functions

func EnsureLocalGitignored

func EnsureLocalGitignored(repoRoot string) (added bool, warning string, err error)

EnsureLocalGitignored makes sure SpecScore's user-local configuration and persistent lifecycle lock identities are git-ignored in repoRoot, appending missing entries to .gitignore. It returns whether any entry was added and a non-empty warning when specscore.local.yaml is already git-tracked (which defeats its per-user purpose).

func EnsureLocalGitignoredMsg

func EnsureLocalGitignoredMsg(repoRoot string) string

EnsureLocalGitignoredMsg ensures the ignore entry and returns a single advisory message for callers to surface (empty when there is nothing to report). It never returns an error — a failure is folded into the message — so callers need only check for a non-empty string.

Types

type CommittedScopeViolation

type CommittedScopeViolation struct {
	Key string
}

CommittedScopeViolation reports a user-scoped key found in the committed project file where it is not allowed.

func CheckCommittedScope

func CheckCommittedScope(repoRoot string) ([]CommittedScopeViolation, error)

CheckCommittedScope reads the committed project layer (specscore.yaml) at repoRoot and returns a violation for each user-scoped key present in it. The local and home layers are not inspected — user-scoped keys are allowed there. A missing project file yields no violations; a malformed one errors.

func CheckCommittedScopeMap added in v0.50.0

func CheckCommittedScopeMap(m map[string]any) []CommittedScopeViolation

CheckCommittedScopeMap is CheckCommittedScope's pure core: given an already-parsed committed-layer map, it returns a violation for each user-scoped key present. Exported so a caller that has already read and parsed the committed file for its own purposes (e.g. pkg/planstore.Resolve, which needs to reject a committed repo_checkouts specifically) can reuse the exact same key registry and traversal logic — the two enforcement sites cannot drift — without a second, redundant file read whose error path would otherwise be unreachable given the caller already parsed the same file successfully once.

type Resolved

type Resolved struct {
	// Values is the deep-merged configuration tree.
	Values map[string]any
	// Origin maps a dotted leaf key path to the layer it resolved from:
	// one of "local", "project", or "home".
	Origin map[string]string
}

Resolved is the merged configuration plus the per-key source layer.

func ResolveDir

func ResolveDir(repoRoot, homeDir string) (Resolved, error)

ResolveDir resolves layered config for a repo root and a home directory. Missing layer files are treated as empty layers (not errors); a malformed layer file is a hard error.

func ResolveDirWithOrg added in v0.50.0

func ResolveDirWithOrg(repoRoot, homeDir, orgPath string) (Resolved, error)

ResolveDirWithOrg includes an optional organization configuration path between the user and committed project layers.

Jump to

Keyboard shortcuts

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