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
- func ConfigPath(root string) string
- func IsSingletonKind(kind string) bool
- func LockPath(root string) string
- func MarshalSkeleton(s Skeleton) ([]byte, error)
- func RemoveKey(src []byte, key string) ([]byte, error)
- func RootDir(root string) string
- func SetArray(src []byte, key string, values []string) ([]byte, error)
- func SetArrayMember(src []byte, key, name string, add bool) ([]byte, error)
- func SetMappingScalar(src []byte, key, child string, value bool) ([]byte, error)
- func ValidateArtifactName(kind, name string) error
- func ValidateDomainName(name string) error
- type AuditConfig
- type BootstrapConfig
- type CatalogTrim
- type Config
- type HooksConfig
- type InvariantConfig
- type InvariantSource
- type ScopeSpec
- type SectionOverride
- type Sidecar
- type Skeleton
- type SkeletonAudit
Constants ¶
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
ConfigPath returns the skeleton config.yaml path for a project root.
func IsSingletonKind ¶
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 MarshalSkeleton ¶
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
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
RootDir returns the config-tree directory for a project root (<root>/.awf).
func SetArray ¶ added in v0.4.0
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 ¶
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
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 ValidateArtifactName ¶ added in v0.10.0
ValidateArtifactName reports whether name is usable as a local skill/agent name (ADR-0068): non-empty lowercase kebab-case (letters, digits, hyphens). The charset is frontmatter-safe — it excludes the path separators and ".." the invariant requires, awf's reserved "_" namespace, and the colon/space/quote characters that would otherwise interpolate into the base template's name: line and break its YAML frontmatter. It mirrors every catalog artifact's naming. invariant: local-name-validated
func ValidateDomainName ¶
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 ¶
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 ¶
Load reads <awfDir>/config.yaml with the strict decoder, records awfDir as the sidecar/part resolution root, and defaults DocsDir.
func (*Config) HasSidecar ¶ added in v0.10.0
HasSidecar reports whether a declaring sidecar file exists for an artifact — the presence signal that marks a non-catalog name as an intentional local artifact rather than a typo (ADR-0068).
func (*Config) Sidecar ¶
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).
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 ¶
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
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).
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.