config

package
v0.8.0 Latest Latest
Warning

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

Go to latest
Published: Jul 4, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package config loads and validates the per-project .awf/ configuration: a skeleton config.yaml plus per-target sidecar YAMLs and convention parts.

Index

Constants

View Source
const DirName = ".awf"

DirName is the config-tree directory name at the project root.

Variables

This section is empty.

Functions

func ConfigPath added in v0.6.0

func ConfigPath(root string) string

ConfigPath returns the skeleton config.yaml path for a project root.

func IsSingletonKind

func IsSingletonKind(kind string) bool

IsSingletonKind reports whether kind is an always-on singleton whose sidecar lives at <root>/<kind>.yaml and whose parts live under <root>/parts/<kind>/ (ADR-0021, ADR-0043).

func LockPath added in v0.6.0

func LockPath(root string) string

LockPath returns the awf.lock path for a project root.

func MarshalSkeleton

func MarshalSkeleton(s Skeleton) ([]byte, error)

MarshalSkeleton renders a fresh config.yaml from s in the canonical awf format (two-space block style). It is the construction half of internal/config's ownership of config.yaml serialization (ADR-0026).

func RemoveKey added in v0.2.0

func RemoveKey(src []byte, key string) ([]byte, error)

RemoveKey deletes the top-level mapping entry under key from a config.yaml source via a yaml.Node round-trip that preserves comments and every untouched key (ADR-0026). Removing an absent key is a no-op (returns src unchanged), so a schema migration can re-run safely.

func RootDir added in v0.6.0

func RootDir(root string) string

RootDir returns the config-tree directory for a project root (<root>/.awf).

func SetArray added in v0.4.0

func SetArray(src []byte, key string, values []string) ([]byte, error)

SetArray sets the sequence under key to exactly values, creating the key if it is absent and replacing it otherwise, via a yaml.Node round-trip that preserves comments and every untouched key (ADR-0026). Used where the whole list is computed rather than edited member-by-member — the targets array carries a Load default, so an absent on-disk key must be materialized as the full resolved list, not appended to (ADR-0037).

func SetArrayMember

func SetArrayMember(src []byte, key, name string, add bool) ([]byte, error)

SetArrayMember adds or removes name in the sequence under key in a config.yaml source, via a yaml.Node round-trip that preserves comments and every untouched key (ADR-0026). The edited sequence is normalized to block style, so a flow-style input (`key: [a, b]`) is accepted. Adding a member already present is a no-op; removing a member absent from the key (or a key absent on remove) errors. invariant: config-mutation-roundtrip

func SetMappingScalar added in v0.5.0

func SetMappingScalar(src []byte, key, child string, value bool) ([]byte, error)

SetMappingScalar sets child to a bool value under a top-level mapping at key in a config.yaml source, creating the key's mapping (and the child) if absent, via a yaml.Node round-trip that preserves comments and every untouched key (ADR-0026). It is the nested-scalar analog of SetArray (which writes a sequence): the bootstrap enable entry is `bootstrap.enabled: <bool>`, not an enable array, so it needs a mapping-scalar writer rather than SetArrayMember. An existing scalar under key/child is overwritten.

func ValidateDomainName

func ValidateDomainName(name string) error

ValidateDomainName reports whether name is a usable domain key: non-empty and free of path separators or "..". Shared by Validate and the `awf add domain` path so a freeform domain name is rejected the same way in both.

Types

type AuditConfig

type AuditConfig struct {
	BaseBranch          string      `yaml:"baseBranch"`
	AllowedTypes        []string    `yaml:"allowedTypes"`
	AllowedScopes       []ScopeSpec `yaml:"allowedScopes"`
	SubjectMaxLength    *int        `yaml:"subjectMaxLength"`
	DependencyManifests []string    `yaml:"dependencyManifests"`
	DiffThreshold       *int        `yaml:"diffThreshold"`
	DomainDocStaleness  *bool       `yaml:"domainDocStaleness"`
	UndocumentedDomain  *bool       `yaml:"undocumentedDomain"`
	UncommittedChanges  *bool       `yaml:"uncommittedChanges"`
}

AuditConfig tunes `awf audit` (ADR-0017). A nil *AuditConfig means all defaults; within it, a nil slice means "use the default", an explicit empty slice means "accept any / disabled" per field. Resolution and defaults live in internal/audit (audit.Resolve), which owns the audit domain semantics.

type BootstrapConfig added in v0.5.0

type BootstrapConfig struct {
	Enabled bool `yaml:"enabled"`
}

BootstrapConfig configures the rendered .awf/bootstrap.sh singleton (ADR-0040, relocated by ADR-0047). A nil *BootstrapConfig (key absent) and Enabled false both mean "do not render"; only Enabled true renders the artifact — a nested enable entry rather than a top-level scalar bool (the Alternatives table rejected the bare bool).

type CatalogTrim

type CatalogTrim struct {
	Skills *[]string
	Docs   *[]string
}

CatalogTrim optionally overrides which catalog skills/docs a scaffolded config enables (ADR-0029 catalog trim). A nil *CatalogTrim — or a nil dimension within it — means "no selection: keep the curated-core default"; a non-nil dimension is the verbatim, fully-deselectable enable set (an empty slice deselects all).

type Config

type Config struct {
	Prefix     string           `yaml:"prefix"`
	DocsDir    string           `yaml:"docsDir"`
	Vars       map[string]any   `yaml:"vars"`
	Skills     []string         `yaml:"skills"`
	Agents     []string         `yaml:"agents"`
	Docs       []string         `yaml:"docs"`
	Domains    []string         `yaml:"domains"`
	Targets    []string         `yaml:"targets"`
	Invariants *InvariantConfig `yaml:"invariants"`
	Audit      *AuditConfig     `yaml:"audit"`
	Bootstrap  *BootstrapConfig `yaml:"bootstrap"`
	Hooks      *HooksConfig     `yaml:"hooks"`
	// contains filtered or unexported fields
}

Config is the skeleton config.yaml: global fields plus flat enable arrays. Presence of a name in Skills/Agents/Docs enables that artifact; per-artifact data/sections/local live in sidecars, not here. Targets is the adapter-runtime enable array (default ["claude"]); adapter artifacts render once per entry.

func Load

func Load(awfDir string) (*Config, error)

Load reads <awfDir>/config.yaml with the strict decoder, records awfDir as the sidecar/part resolution root, and defaults DocsDir.

func (*Config) PartPath

func (c *Config) PartPath(kind, artifact, section string) string

PartPath returns the convention part path for a section of an artifact.

func (*Config) Sidecar

func (c *Config) Sidecar(kind, name string) (Sidecar, error)

Sidecar reads <root>/<kind>/<name>.yaml; agents-doc lives at <root>/agents-doc.yaml. A missing file yields a zero Sidecar (publication-safe: empty data/sections).

func (*Config) Validate

func (c *Config) Validate() error

type HooksConfig added in v0.6.0

type HooksConfig struct {
	Enabled bool `yaml:"enabled"`
}

HooksConfig configures the rendered .awf/hooks/ payload singleton (ADR-0048): three inert git-hook payload scripts adopters wire into hook setups they own. BootstrapConfig semantics: a nil *HooksConfig (key absent) and Enabled false both mean "do not render"; only Enabled true renders the payloads. The key reuses the name the schema-4 drop-hooks migration stripped (ADR-0032); the legacy array shape never reaches this struct — gated commands migrate first, ungated ones fail loudly on the strict parser's type error.

type InvariantConfig

type InvariantConfig struct {
	Disabled bool              `yaml:"disabled"`
	Sources  []InvariantSource `yaml:"sources"`
}

InvariantConfig configures language-agnostic invariant backing. A nil *InvariantConfig (key absent) means "unchecked"; Disabled is the explicit opt-out; a non-empty Sources enables enforcement.

type InvariantSource

type InvariantSource struct {
	Globs  []string `yaml:"globs"`
	Marker string   `yaml:"marker"`
}

InvariantSource pairs filename globs (matched against a file's basename) with the literal comment marker that prefixes a backing `invariant: <slug>` tag.

type ScopeSpec added in v0.8.0

type ScopeSpec struct {
	Name    string `yaml:"name"`
	Meaning string `yaml:"meaning"`
}

ScopeSpec is one allowed commit scope: a name and an optional human meaning. In config a scope is written either as a bare string (name only) or a {name, meaning} mapping (ADR-0056).

func (*ScopeSpec) UnmarshalYAML added in v0.8.0

func (s *ScopeSpec) UnmarshalYAML(n *yaml.Node) error

UnmarshalYAML accepts either a scalar node (the bare-string form → empty meaning) or a strict mapping node. invariant: scope-config-dual-form

type SectionOverride

type SectionOverride struct {
	Drop bool `yaml:"drop"`
}

SectionOverride is a sidecar's per-section override. Body replacement is by convention part only; the field set is deliberately just Drop. invariant: no-replacewith

type Sidecar

type Sidecar struct {
	Data     map[string]any             `yaml:"data"`
	Sections map[string]SectionOverride `yaml:"sections"`
	Local    bool                       `yaml:"local"`
}

Sidecar holds a single target's non-prose configuration: structured render data, per-section overrides, and the local flag. It lives at <awfDir>/<kind>/<name>.yaml (agents-doc: <awfDir>/agents-doc.yaml). An absent sidecar is the zero Sidecar (publication-safe: empty data/sections).

type Skeleton

type Skeleton struct {
	Prefix     string            `yaml:"prefix"`
	Vars       map[string]string `yaml:"vars"`
	Skills     []string          `yaml:"skills"`
	Agents     []string          `yaml:"agents"`
	Docs       []string          `yaml:"docs"`
	Audit      *SkeletonAudit    `yaml:"audit,omitempty"`
	Invariants *InvariantConfig  `yaml:"invariants,omitempty"`
	Bootstrap  *BootstrapConfig  `yaml:"bootstrap,omitempty"`
	Hooks      *HooksConfig      `yaml:"hooks,omitempty"`
}

Skeleton is the input to MarshalSkeleton: the fields a freshly-scaffolded .awf/config.yaml carries. Vars is typed map[string]string (not map[string]any) so a nil/null var value is unrepresentable — the scaffold seeds each var with an empty string, which marshals as `x: ""`. A nil interface would marshal as `x: null` and decode back to a nil value that renders as "<no value>", tripping the publication-safe check (ADR-0026 Decision 3).

type SkeletonAudit added in v0.6.0

type SkeletonAudit struct {
	AllowedScopes []string `yaml:"allowedScopes"`
}

SkeletonAudit is the audit block a scaffold can seed (ADR-0051): only allowedScopes — the one audit field init collects. Deliberately not *AuditConfig, whose zero-value fields would serialize as explicit settings.

Jump to

Keyboard shortcuts

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