Documentation
¶
Index ¶
- Constants
- Variables
- func AssertNormalized(cfg *Config) error
- func BodyRefs(body string) []string
- func CIBranch() string
- func CIEvent() string
- func CIProvider() string
- func CITag() string
- func DeepMerge(base, override *yaml.Node) *yaml.Node
- func EventMatches(events []string, current string) bool
- func ForgeLinkBase(provider, baseURL, projectID, branch string) (string, error)
- func ForgeRawBase(provider, baseURL, projectID, branch string) (string, error)
- func HostOf(raw string) string
- func IdentitySubs(cfg *Config) map[string]string
- func IsShippedStencilID(id string) bool
- func LLMTaintedStencils(stencils OrderedStencils) map[string]bool
- func LoadWithReport(path string) (*Config, ConfigReport, []MergeEntry, error)
- func MatchCondition(c Condition) bool
- func MatchConditionWith(c Condition, tag, branch string) bool
- func MatchPatterns(patterns []string, value string) bool
- func MatchPatternsWithPolicy(patterns []string, value string, policyMap map[string]string) bool
- func MessageHasTrailer(msg, trailer string) bool
- func MigrateToLatest(data []byte) ([]byte, error)
- func Normalize(cfg *Config) error
- func NormalizeEvent(raw string) string
- func OriginTrailer(origin string) string
- func ParseDuration(s string) (time.Duration, error)
- func ParseForgeURL(rawURL string) (provider, baseURL, projectID string, err error)
- func ParseSize(s string) (int64, error)
- func PrimaryDefaultBranch(cfg *Config) string
- func PrimaryURL(cfg *Config) string
- func PrimaryWorktree(cfg *Config) string
- func ResolveLinkBase(cfg *Config) (string, error)
- func ResolvePatterns(patterns []string, patternMap map[string]string) []string
- func ResolvePublishOrigin(cfg *Config) (string, error)
- func SlugFromPrimary(cfg *Config) string
- func TargetIsUnconditional(t TargetConfig) bool
- func TargetMatches(t TargetConfig, event, branch, tag, forge string, ...) bool
- func TargetMatchesEnv(t TargetConfig, cfg *Config) bool
- func ValidArchiveFormats() []string
- func ValidBuildKinds() []string
- func ValidBuilders() []string
- func ValidEvents() []string
- func ValidLintLevels() []string
- func ValidManifestModes() []string
- func ValidOutputTypes() []string
- func ValidTargetKinds() []string
- func ValidTrustClasses() []string
- func Validate(cfg *Config) (warnings []string, err error)
- func ValidateIdentityGraph(forges []ForgeConfig, repos []RepoConfig, registries []RegistryConfig) []string
- func ValidatePreset(content []byte) (string, *yaml.Node, error)
- func ValidateSigningConfig(c SigningConfig) []string
- func ValidateSigningProfiles(profiles []SigningProfile) []string
- func ValidateTargetRegistryRefs(targets []TargetConfig, registries []RegistryConfig) []string
- func ValidateTargetRepoRefs(targets []TargetConfig, repos []RepoConfig) []string
- func ValidateTargetSigningProfileRefs(targets []TargetConfig, profiles []SigningProfile) []string
- type AgePruneRule
- type AnsibleConfig
- type AnsiblePlaybook
- type AnsibleSSH
- type BadgeSpec
- type BranchBuildConfig
- type BranchesConfig
- type BreakingConfig
- type BuildCacheConfig
- type BuildCachePrunePolicy
- type BuildConfig
- type BuilderConfig
- type CIConfig
- type CacheConfig
- type ClusterConfig
- type CommandSpec
- type CommitConfig
- type CommitPresentation
- type CommitType
- type CompiledPatterns
- type Condition
- type Config
- type ConfigReport
- type ContainerPrunePolicy
- type CrucibleConfig
- type DependencyCIConfig
- type DependencyCommitConfig
- type DependencyCommitPromotion
- type DependencyConfig
- type DependencyHandoff
- type DependencyIgnore
- type DependencyMRConfig
- type DependencyScopeConfig
- type DetailRule
- type DockerDriftPolicy
- type DockerIaCConfig
- type DockerLifecycleConfig
- type DockerSecretsConfig
- type DockerTargetSelector
- type DockerTargetsConfig
- type ExposureRule
- type ExposureRules
- type ExternalCacheConfig
- type ExternalRetention
- type FacetSpec
- type FileDef
- type FilterConfig
- type ForgeConfig
- type Gate
- type GitConfig
- type GitOpsCluster
- type GitVersioning
- type GlossaryConfig
- type GlossaryType
- type GovernanceConfig
- type GovernanceProfile
- type HostCleanupConfig
- type IDMap
- type ImageProtection
- type ImagePrunePolicy
- type KMSTrust
- type KeyTrust
- type LLMConfig
- type Level
- type LifecycleConfig
- type LifecycleMode
- type LintCacheConfig
- type LintConfig
- type LocalCacheConfig
- type LocalRetention
- type ManifestConfig
- type MatchResult
- type MergeEntry
- type MergeTrace
- type MetadataConfig
- type MirrorSync
- type ModuleConfig
- type NarrateConfig
- type NetworkPrunePolicy
- type NoLineageConfig
- type Notification
- type OIDCConfig
- type OIDCTrust
- type OrderedAnsiblePlaybooks
- type OrderedBranchBuilds
- type OrderedBuilds
- type OrderedClusters
- type OrderedFiles
- type OrderedForges
- type OrderedGovProfiles
- type OrderedLLMs
- type OrderedNotifications
- type OrderedOrgs
- type OrderedRegistries
- type OrderedRepos
- type OrderedSigningProfiles
- type OrderedStencils
- type OrderedTagSources
- type OrderedTargets
- type OrderedTestSuites
- type OrgConfig
- type OutdatedGate
- type OutputSpec
- type PKCS11Trust
- type PagesVersioning
- type PhraseRewrite
- type PresetLoader
- type PresetSource
- type ProducerCoords
- type ProtectionPolicy
- type ProvenanceConfig
- type PrunePolicy
- type RegexRewrite
- type RegistryConfig
- type ReleaseConfig
- type ReleasePresentation
- type RemediationConfig
- type RenderConfig
- type RepoConfig
- type ResolvedRegistry
- type ResolvedRepo
- func ResolveAllMirrors(repos []RepoConfig, forges []ForgeConfig, vars map[string]string) ([]*ResolvedRepo, error)
- func ResolvePrimary(repos []RepoConfig, forges []ForgeConfig, vars map[string]string) (*ResolvedRepo, error)
- func ResolveRepo(repo RepoConfig, forges []ForgeConfig, vars map[string]string) (*ResolvedRepo, error)
- type ResolvedSigningProfile
- type RetentionPolicy
- type RetentionRef
- type RewriteConfig
- type RoutingConfig
- type RoutingSpec
- type RunFromConfig
- type RunFromResult
- type ScannerCacheConfig
- type ScannersConfig
- type Scoped
- type ScribeCommit
- type ScribeConfig
- type SectionState
- type SecurityCacheConfig
- type SecurityConfig
- type SecurityException
- type SigningConfig
- type SigningProfile
- type StageConfig
- type StateDir
- type StencilDef
- type StringOrList
- type SummaryFilter
- type SyncConfig
- type SyncTopology
- type TagConfig
- type TagDefaults
- type TagMessage
- type TagPresentation
- type TagSourceConfig
- type TargetCondition
- type TargetConfig
- type TestConfig
- type TestSuite
- type TestTool
- type ToolConstraint
- type ToolchainConfig
- type ToolchainSection
- type TrailerFilter
- type VolumeProtection
- type WatchRule
- type WhenConditions
- type WorktreeOutput
- type WorktreeSpec
Constants ¶
const ( OriginNarrate = "narrate" OriginDeps = "deps" OriginGovernance = "governance" )
Commit origins — the StageFreight path that authored a commit, and the git-native provenance trailer each carries. Both are our own trailers (they read like Signed-off-by, fire no forge CI-skip matcher, and are not forge-recognized so they trigger no avatar attribution). The verb is the whole signal — no parenthetical — and it lines up with the CI decision:
narrate → Generated-By: StageFreight generation (docs/badges from code); no build
impact → the CI rules SKIP its branch push.
deps → Updated-By: StageFreight an update to existing dependencies; changes what
the image ships → it still BUILDS (rebuild + republish).
govern → Governed-By: StageFreight policy distributed from a control repo; changes the
config the repo builds UNDER → it must BUILD, or the
satellite never runs under the policy just given to
it. Distinct from Updated-By so `git log --grep` can
separate a reconcile from a dependency bump; no
behaviour keys on either, both are provenance.
A manual `stagefreight commit` or a human commit carries no trailer — SF-authorship is already inferable from the commit author, and it builds by default. `Co-authored-by` is deliberately NOT used: it's a forge-recognized attribution trailer, reserved for the day StageFreight authors real code, not an automated docs/deps pass.
const ( // GeneratedByTrailer marks a narrate commit (generated docs/badges); the CI rules key // on it to skip the branch pipeline, since regenerating would only re-emit it (the loop). GeneratedByTrailer = "Generated-By: StageFreight" // UpdatedByTrailer marks a deps commit (updated dependencies); provenance only — the CI // does NOT skip on it, because the image must rebuild to ship the update. UpdatedByTrailer = "Updated-By: StageFreight" // GovernedByTrailer marks a governance reconcile (policy distributed from a control // repo); provenance only, and likewise NOT skipped — the satellite must build under the // config it was just given. GovernedByTrailer = "Governed-By: StageFreight" )
const ( ModeImage = "image" ModeGitops = "gitops" ModeDocker = "docker" ModeGovernance = "governance" )
Lifecycle mode identifiers — the CANONICAL set. A mode selects phase-BODY behavior (build vs reconcile) and which mode-specific config block applies; it never gates a phase — the five phases (audition/perform/review/publish/narrate) run for every mode. These constants and the lifecycleModes table below are the single source of truth: dispatch sites and the validator read them instead of hardcoding `case "gitops"` literals.
const ( TrustKey = "key" TrustOIDC = "oidc" TrustKMS = "kms" TrustHardware = "hardware" )
Trust classes — the only valid `requires` values after normalization.
const DefaultAnsibleImage = "docker.io/hlhd/ansible:latest"
DefaultAnsibleImage is the official execution image. Repos normally pin an explicit version tag; the bare default exists so local plan/lint work before the pin is chosen.
const ShippedNotificationSubject = "{project} {ref} — {status} in {duration}"
ShippedNotificationSubject is the default notification title — a freeform body like everything else. No {status_icon}: ntfy renders the notification's Tags emoji in front of the title already (white_check_mark / rotating_light), and two icons read as a stutter. The fact stays available for custom subjects. {duration} is elapsed from the run's first recorded state write.
Variables ¶
var DefaultScribeStore = path.Join(paths.Root, paths.ScribeName)
DefaultScribeStore is the default directory for scribe-rendered file assets (badge SVGs, and any future rendered files). Named after the subsystem, consistent with .stagefreight/security, .stagefreight/deps, .stagefreight/manifests. Derived from paths so the durable allowlist (workspace) carves out this exact directory.
var SourceFetcher presetref.Fetcher
SourceFetcher is the injected remote-preset fetcher. It is nil by default — in that state a sourced preset ref resolves from the preset-cache only (offline), erroring on a miss. A network-capable entry point (the CLI) sets it at startup so tracked/pinned refs fetch live. This is a set-once startup seam, not a per-call mutable global.
Functions ¶
func AssertNormalized ¶ added in v0.5.0
AssertNormalized verifies no unresolved {var:} templates remain in the config, and that no identity token ({org*}/{orgs.*}/{metadata.*}/{path.*}/{slug}) survived the identity pass outside the (opaque) governance payload — a survivor means a typo'd alias/field or a missing orgs/metadata declaration, and failing loudly here beats a malformed push ref or a forge 404 later. Hard failure — not a warning.
func BodyRefs ¶ added in v0.8.0
BodyRefs scans a body for {name} embed tokens (skipping {{…}} literal escapes) and returns the names in order of appearance. It mirrors the stencil engine's brace scan so validation (cycle detection) and rendering agree on what a body references.
func CIBranch ¶ added in v0.7.0
func CIBranch() string
CIBranch returns the current branch from the CI environment ("" if none).
func CIEvent ¶ added in v0.7.0
func CIEvent() string
CIEvent derives the current CI event in the canonical when.events vocabulary. Tag presence (CI_COMMIT_TAG / SF_CI_TAG) is the authoritative push-vs-tag signal: GitLab reports CI_PIPELINE_SOURCE=push even for tag pushes, and the dev channel synthesizes its tag locally (never exporting SF_CI_TAG), so a tag *string* is not a reliable event signal. Otherwise the raw forge source (SF_CI_EVENT) is mapped to the canonical vocabulary via NormalizeEvent, so gates authored once (events:[manual]) match on every forge despite their differing raw names.
func CIProvider ¶ added in v0.7.0
func CIProvider() string
CIProvider returns the current forge provider (github/gitlab/gitea/forgejo) from the CI environment ("" if none), for forge-scoped target eligibility.
func CITag ¶ added in v0.7.0
func CITag() string
CITag returns the current tag from the CI environment ("" if none).
func DeepMerge ¶ added in v0.6.0
DeepMerge deep-merges override into base (both mapping nodes), override wins. Objects deep-merge (base order preserved, new keys appended); scalars/sequences replace. Non-mapping inputs: override replaces.
func EventMatches ¶ added in v0.7.0
EventMatches reports whether the current CI event satisfies a target's when.events filter. It is the shared primitive for event-aware target routing (release targets, binary-archive gating). The current event is expected in the canonical vocabulary (see NormalizeEvent) — CIEvent normalizes at the env boundary, so this primitive never sees a raw forge source name.
Semantics:
- An empty filter (no events: declared) means no filtering — always true.
- An empty current event (unknown) also means no filtering — events are enforced only when the event is known, so non-CI/manual paths stay lenient.
- Comparison is case-insensitive and trims surrounding whitespace.
- A push-equivalent event (manual or schedule — see pushEquivalent) satisfies a "push" gate as well as its own literal gate name, so manual re-runs and scheduled auto-release pipelines distribute exactly what a push would. The relation is one-way: a plain "push" does NOT satisfy a manual-/schedule-only gate.
func ForgeLinkBase ¶ added in v0.5.0
ForgeLinkBase constructs a page-link (blob) base URL from forge fields. Used for resolving relative links (e.g., LICENSE → blob URL).
func ForgeRawBase ¶ added in v0.5.0
ForgeRawBase constructs a raw content base URL from forge mirror fields. Handles GitLab subgroup paths (group/subgroup/project) correctly. All inputs are normalized to prevent double-slash artifacts.
func HostOf ¶ added in v0.9.0
HostOf extracts the lowercased hostname (no scheme, no port, no path, no userinfo) from a URL or bare host string, for EXACT host matching. "https://gitlab.example.com:443/o/r" and "gitlab.example.com" both normalize to "gitlab.example.com". Returns "" when the input has no resolvable host. This is the single host-identity primitive used to bind a git credential to the forge that owns the destination host.
func IdentitySubs ¶ added in v0.10.0
IdentitySubs builds the brace-delimited token → value map from config. Tokens are brace-delimited so none is a substring of another as a whole token (e.g. "{org}" never matches inside "{org.lower}"), making ReplaceAll order-independent. Only tokens the config can populate are added; a typo'd token has no entry, stays literal, and the normalization assertion rejects it loudly.
func IsShippedStencilID ¶ added in v0.8.0
IsShippedStencilID reports whether id names a shipped default stencil (valid to announce or embed without a user declaration).
func LLMTaintedStencils ¶ added in v0.8.0
func LLMTaintedStencils(stencils OrderedStencils) map[string]bool
LLMTaintedStencils returns every stencil id whose output can carry AI text: the type: llm stencils plus any text stencil embedding a tainted stencil, transitively (fixpoint). AI output is DISPATCH-ONLY — stdout cards and notifications — never the committed record: scribe file regions reject these ids at validation (the determinism boundary).
func LoadWithReport ¶ added in v0.6.0
func LoadWithReport(path string) (*Config, ConfigReport, []MergeEntry, error)
LoadWithReport loads config and returns a ConfigReport with real provenance. It also returns the raw per-value merge entries so callers that want per-value provenance (e.g. `config resolve --verbose`) render from the SAME resolution — no second resolve. Entries are nil for an absent/preset-free config.
func MatchCondition ¶
MatchCondition evaluates a Condition against the current CI environment. Returns true if all present fields match (AND logic). Empty condition = catch-all (always true).
func MatchConditionWith ¶
MatchConditionWith evaluates a Condition against explicit tag/branch values. Use this when you already have the values resolved (e.g., from git detection).
func MatchPatterns ¶
MatchPatterns evaluates a list of patterns against a value (OR logic). Any pattern matching means the value is allowed. Empty list = always allowed (no filter). Supports ! negation — a negated pattern excludes even if others include.
Evaluation: exclude patterns (!) are checked first. If any exclude matches, the value is rejected. Then include patterns are checked — if any matches, the value is allowed. If only exclude patterns exist and none matched, the value is allowed (exclude-only = allowlist by negation).
func MatchPatternsWithPolicy ¶
MatchPatternsWithPolicy resolves named patterns and evaluates them against a value. Convenience wrapper combining ResolvePatterns + MatchPatterns. (Name retained for backward compat with existing call sites.)
func MessageHasTrailer ¶ added in v0.9.0
MessageHasTrailer reports whether msg carries trailer as a whole line. A git trailer sits on its own line (and is the last line for SF's own commits, per commit.Plan.Message), so matching the full line — not a substring — prevents a commit whose PROSE merely mentions the trailer (e.g. one describing this very skip rule) from being mistaken for a generated commit. The CI-render layer anchors equivalently (GitLab `(?m)^…`, Actions `endsWith`).
func MigrateToLatest ¶
MigrateToLatest takes raw YAML data and migrates it to the current schema version. Returns the migrated YAML bytes ready for writing.
Migration chain:
version 1 → current (no-op, already latest)
Future schema changes should add migration steps here (e.g., v1→v2). The old pre-version config was an unversioned alpha that never earned a schema number — it is not convertible and is not supported by this migration path.
func Normalize ¶ added in v0.5.0
Normalize resolves all {var:...} templates throughout the entire config. Walks every string in the config graph recursively — structs, maps, slices, interfaces. No field enumeration. No partial coverage.
Called once after load+validate, before any consumer reads the config.
func NormalizeEvent ¶ added in v0.9.2
NormalizeEvent maps a forge's raw pipeline-source string to the canonical when.events vocabulary (see validEvents), so a config gate is written once in portable terms and matches on every forge. The raw source is CI_PIPELINE_SOURCE on GitLab, github.event_name on GitHub/Gitea/Forgejo, and Build.Reason on Azure — and the single "manual re-run" concept has five different raw names across them (web/api/trigger, workflow_dispatch, Manual), which all collapse to "manual". An unrecognized source passes through lowercased (lenient: it still matches a literally-named gate), and empty stays empty (the unknown-event lenience in EventMatches then applies).
func OriginTrailer ¶ added in v0.8.0
OriginTrailer returns the provenance trailer for a StageFreight commit origin, or "" for a manual/human commit (no trailer). The commit layer writes it; the CI-render layer keys its skip rule on GeneratedByTrailer.
func ParseDuration ¶ added in v0.5.0
ParseDuration parses a human duration like "7d", "72h", "30m". Extends time.ParseDuration with "d" (days) support.
func ParseForgeURL ¶ added in v0.5.0
ParseForgeURL detects forge provider from a full repository URL, extracts base URL and project ID. Examples:
"https://github.com/PrPlanIT/StageFreight" → github, "https://github.com", "PrPlanIT/StageFreight" "https://gitlab.prplanit.com/SoFMeRight/dungeon" → gitlab, "https://gitlab.prplanit.com", "SoFMeRight/dungeon"
func ParseSize ¶ added in v0.5.0
ParseSize parses a human size like "15GB", "500MB", "100KB". Uses binary units (1 GB = 1024³ bytes).
func PrimaryDefaultBranch ¶ added in v0.6.0
PrimaryDefaultBranch returns the default branch of the primary repo.
func PrimaryURL ¶ added in v0.6.0
PrimaryURL returns the full URL of the primary repo, or empty string. Thin wrapper over ResolvePrimary for call sites that only need the URL.
func PrimaryWorktree ¶ added in v0.6.0
PrimaryWorktree returns the worktree path of the primary repo, or ".".
func ResolveLinkBase ¶ added in v0.5.0
ResolveLinkBase resolves the page-link (blob) base URL for relative links. Uses the repo with publish-origin role, falling back to primary.
func ResolvePatterns ¶
ResolvePatterns resolves named tokens in a pattern list to their regex values from the provided name→regex map (e.g. matchers.branches or a flattened tag_sources map). It is the single resolver for the full when: pattern vocabulary: named policies, bare/`re:`-prefixed regex, and `!` negation. A "re:" prefix forces inline-regex interpretation, bypassing named-pattern lookup; bare patterns pass through unchanged; negation is preserved.
func ResolvePublishOrigin ¶ added in v0.5.0
ResolvePublishOrigin resolves the serving base URL for rendered artifacts. Uses the repo with publish-origin role, falling back to primary.
func SlugFromPrimary ¶ added in v0.10.0
SlugFromPrimary is the repo's name that coordinates default {repo} to: the LITERAL primary repo location's last segment. "" when no primary exists or its project is still templated (which cannot anchor a slug).
func TargetIsUnconditional ¶ added in v0.7.0
func TargetIsUnconditional(t TargetConfig) bool
TargetIsUnconditional reports whether a target declares no when: constraints at all (no events, branches, or git_tags) — i.e. it is eligible in every CI context. It exists so callers can ask this WITHOUT reading t.When.* directly: an emptiness probe is still an interpretation of target constraints, and per the eligibility-routing invariant there is exactly one interpreter (this package).
func TargetMatches ¶ added in v0.7.0
func TargetMatches(t TargetConfig, event, branch, tag, forge string, tagPolicies, branchPolicies map[string]string) bool
TargetMatches reports whether a target's when: conditions are satisfied — the bool view of TargetEligibility for call sites that don't narrate. See the TargetEligibility invariant: this is the single shared gating predicate; capabilities must not interpret when: themselves.
func TargetMatchesEnv ¶ added in v0.7.0
func TargetMatchesEnv(t TargetConfig, cfg *Config) bool
TargetMatchesEnv evaluates TargetMatches against the current CI environment, resolving policy maps from cfg. Convenience for contributors that gate on when:.
func ValidArchiveFormats ¶ added in v0.8.0
func ValidArchiveFormats() []string
ValidArchiveFormats returns the recognized binary-archive format values.
func ValidBuildKinds ¶ added in v0.8.0
func ValidBuildKinds() []string
ValidBuildKinds returns the recognized builds[].kind values.
func ValidBuilders ¶ added in v0.8.0
func ValidBuilders() []string
ValidBuilders returns the recognized builds[].builder values.
func ValidEvents ¶ added in v0.8.0
func ValidEvents() []string
ValidEvents returns the recognized targets[].when.events values.
func ValidLintLevels ¶ added in v0.8.0
func ValidLintLevels() []string
ValidLintLevels returns the recognized lint.level values.
func ValidManifestModes ¶ added in v0.8.0
func ValidManifestModes() []string
ValidManifestModes returns the recognized manifest.mode values.
func ValidOutputTypes ¶ added in v0.8.0
func ValidOutputTypes() []string
ValidOutputTypes returns the recognized builds[].outputs[].type values.
func ValidTargetKinds ¶ added in v0.8.0
func ValidTargetKinds() []string
ValidTargetKinds returns the recognized targets[].kind values.
func ValidTrustClasses ¶ added in v0.8.0
func ValidTrustClasses() []string
ValidTrustClasses returns the recognized signing.profiles[].requires values.
func Validate ¶
Validate checks structural invariants of a loaded v2 Config. Returns warnings (soft issues) and a hard error if the config is invalid.
func ValidateIdentityGraph ¶ added in v0.6.0
func ValidateIdentityGraph(forges []ForgeConfig, repos []RepoConfig, registries []RegistryConfig) []string
ValidateIdentityGraph checks structural invariants of forges, repos, and registries. Returns all errors found (not just the first).
func ValidatePreset ¶ added in v0.6.0
ValidatePreset parses a preset and enforces exactly one top-level key, returning that key and its value node.
func ValidateSigningConfig ¶ added in v0.7.0
func ValidateSigningConfig(c SigningConfig) []string
ValidateSigningConfig checks the operational signing block. auto_provision needs a state dir (nowhere to persist a Tier-0 identity otherwise — a silent ephemeral key would break continuity on every run).
func ValidateSigningProfiles ¶ added in v0.7.0
func ValidateSigningProfiles(profiles []SigningProfile) []string
ValidateSigningProfiles is the single validation layer for signing policy (Compile in src/sign never re-validates — it is total over validated config). Alias-tolerant (keyless/yubikey accepted; Normalize canonicalizes later).
func ValidateTargetRegistryRefs ¶ added in v0.6.0
func ValidateTargetRegistryRefs(targets []TargetConfig, registries []RegistryConfig) []string
ValidateTargetRegistryRefs checks that targets with registry: reference existing registries, and that registry + inline fields don't conflict.
func ValidateTargetRepoRefs ¶ added in v0.7.0
func ValidateTargetRepoRefs(targets []TargetConfig, repos []RepoConfig) []string
ValidateTargetRepoRefs checks that targets referencing a repo (kind: generic-package) resolve to a declared repos[] entry. Mirrors ValidateTargetRegistryRefs.
func ValidateTargetSigningProfileRefs ¶ added in v0.7.0
func ValidateTargetSigningProfileRefs(targets []TargetConfig, profiles []SigningProfile) []string
ValidateTargetSigningProfileRefs checks each target's signing_profile resolves. An empty reference is valid (→ the synthesized `legacy` profile); the reserved `legacy` id is always valid. Mirrors ValidateTargetRegistryRefs.
Types ¶
type AgePruneRule ¶ added in v0.5.0
type AgePruneRule struct {
OlderThan string `yaml:"older_than,omitempty"` // e.g. "72h"
}
AgePruneRule is a simple age-based prune rule.
type AnsibleConfig ¶ added in v0.9.0
type AnsibleConfig struct {
Preset string `yaml:"preset,omitempty"`
// Backend selects the host-convergence backend. Default: "ansible".
Backend string `yaml:"backend"`
// Image is the execution image the playbooks (and ansible-lint) run in —
// the ansible runtime, collections, and connection deps are the image's
// contract. Fully qualified, version-pinned reference.
// Default: docker.io/hlhd/ansible (the official StageFreight ansible image).
Image string `yaml:"image"`
// Inventory is the repo-relative ansible inventory file.
Inventory string `yaml:"inventory"`
// SSH is the shared connection identity used by every play.
SSH AnsibleSSH `yaml:"ssh"`
// Playbooks is the play library: an order-preserving id → entry map.
// Entries with converge: true run every perform reconcile, in declared
// order; entries with converge: false are runbooks — lintable and
// plannable, but only ever executed by an explicit `ansible run <id>`.
Playbooks OrderedAnsiblePlaybooks `yaml:"playbooks"`
}
AnsibleConfig defines the ansible host-convergence subsystem: a library of declared playbooks executed inside a containerized ansible runtime. It is presence-gated (any converge playbook activates the perform-phase backend) and deliberately independent of lifecycle.mode — ansible runs alongside gitops/governance, never instead of them.
func DefaultAnsibleConfig ¶ added in v0.9.0
func DefaultAnsibleConfig() AnsibleConfig
DefaultAnsibleConfig returns sensible defaults for ansible configuration.
func (AnsibleConfig) ConvergePlaybooks ¶ added in v0.9.0
func (a AnsibleConfig) ConvergePlaybooks() []AnsiblePlaybook
ConvergePlaybooks returns the converge set in declared order.
func (AnsibleConfig) HasConvergePlaybooks ¶ added in v0.9.0
func (a AnsibleConfig) HasConvergePlaybooks() bool
HasConvergePlaybooks reports whether any play is declared converge: true — the presence gate for the perform-phase ansible subsystem.
func (AnsibleConfig) PlaybookByID ¶ added in v0.9.0
func (a AnsibleConfig) PlaybookByID(id string) (AnsiblePlaybook, bool)
PlaybookByID returns the declared play with the given id.
type AnsiblePlaybook ¶ added in v0.9.0
type AnsiblePlaybook struct {
ID string `yaml:"-"`
// Path is the repo-relative playbook file.
Path string `yaml:"path"`
// Groups are the inventory groups this play targets (rendered as --limit).
Groups []string `yaml:"groups"`
// Converge marks the play as desired-state: it runs on every perform
// reconcile. False declares a runbook — a named human operation that CI
// can never trigger.
Converge bool `yaml:"converge"`
// Required: failure is hard pipeline fail (default: true — a converge
// mutates hosts, so a partial apply must never pass silently). Set false
// for advisory plays: a failure is recorded and narrated but the phase
// still exits clean.
Required *bool `yaml:"required,omitempty"`
}
AnsiblePlaybook is one declared play in the library. The map key is its ID.
func (AnsiblePlaybook) IsRequired ¶ added in v0.9.0
func (p AnsiblePlaybook) IsRequired() bool
IsRequired reports whether this play's failure hard-fails the phase. Unset defaults to true.
type AnsibleSSH ¶ added in v0.9.0
type AnsibleSSH struct {
// User is the remote login user on the managed hosts.
User string `yaml:"user"`
// Credentials is the env-prefix name the SSH key material is read from.
Credentials string `yaml:"credentials"`
// KnownHosts is the repo-relative known_hosts file holding the managed
// hosts' public keys. Host-key verification is always strict; the file is
// committed so host trust is auditable in git.
KnownHosts string `yaml:"known_hosts"`
}
AnsibleSSH is the shared SSH connection identity for all plays. The private key is resolved from environment variables at runtime:
- <PREFIX>_SSH_KEY: PEM private key material
- <PREFIX>_SSH_KEY_B64: base64 of the PEM — the single-line form a forge MASKED variable can hold (mirrors the gitops <NAME>_CA_B64 convention)
- <PREFIX>_SSH_KEY_PASSPHRASE: optional key passphrase
Credentials is uppercased with hyphens replaced by underscores to form the env prefix (the same convention as the gitops cluster CA).
func (AnsibleSSH) EnvPrefix ¶ added in v0.9.0
func (s AnsibleSSH) EnvPrefix() string
EnvPrefix derives the environment prefix for SSH credential resolution: uppercased, hyphens to underscores (e.g. "dungeon-nodes" → "DUNGEON_NODES").
type BadgeSpec ¶
type BadgeSpec struct {
Label string // left side text (badge name / alt text)
Value string // right side text (supports templates)
Color string // hex color or "auto"
Output string // SVG file output path
Font string // built-in font name override
FontSize float64 // font size override
FontFile string // custom font file override
}
BadgeSpec is the reusable internal badge specification. Consumed by badge engine, CLI ad-hoc mode, release badge, and docker build badge. No YAML tags — this is an internal model, not a config surface.
type BranchBuildConfig ¶ added in v0.6.0
type BranchBuildConfig struct {
// ID is the unique identifier. "default" is the catch-all entry and must
// appear last in the BranchBuilds slice.
ID string `yaml:"id"`
// Match references a declared branch matcher name. Required for named
// branch_builds entries. The "default" entry rejects Match — it catches
// any branch that did not match a named entry.
Match string `yaml:"match,omitempty"`
// BaseFrom is the ordered fallback chain of tag_sources ids. The runtime
// walks this list in order; for each source id, it scans tags for a match
// and returns the first hit. Fallback advances only when a source yields
// zero matches.
//
// Reads as "look in prerelease first; if nothing, look in stable":
// base_from: [prerelease, stable]
//
// It does NOT mean "prerelease beats stable by priority" — ordering is a
// declared search path, not a ranking.
BaseFrom []string `yaml:"base_from"`
// Format is the version template for non-release commits.
// Supported placeholders: {base}, {sha}, {branch}
// e.g., "{base}-dev+{sha}"
Format string `yaml:"format"`
}
BranchBuildConfig defines how dev versions are formatted for a branch.
type BranchesConfig ¶ added in v0.6.0
type BranchesConfig struct {
// Default is the default branch name (e.g., "main"). Required for primary.
Default string `yaml:"default,omitempty"`
}
BranchesConfig declares branch identity for a repo. Currently carries only Default; reserved for future additions like protected branches, release branches, etc. — those stay on the repo because they're topology, not versioning or promotion.
type BreakingConfig ¶ added in v0.5.0
type BreakingConfig struct {
Aliases []string `yaml:"aliases,omitempty"` // e.g., [b, break, bc]
BangSuffix bool `yaml:"bang_suffix"` // feat! syntax
ForceHighlight bool `yaml:"force_highlight"`
PriorityBoost int `yaml:"priority_boost"`
}
BreakingConfig defines how breaking changes are detected and presented.
type BuildCacheConfig ¶ added in v0.5.0
type BuildCacheConfig struct {
Preset string `yaml:"preset,omitempty"`
// Mode selects which cache planes are active.
// "": inactive — no cache flags emitted, no cleanup runs.
// off: explicitly disabled.
// local: bounded local buildkit cache only.
// shared: registry-backed external cache only.
// hybrid: both local and external.
Mode string `yaml:"mode,omitempty"`
// Builder configures the buildx builder lifecycle.
// The engine owns creation, bootstrap, and narration — skeleton is transport only.
Builder BuilderConfig `yaml:"builder,omitempty"`
// Local configures the bounded local buildkit cache.
Local LocalCacheConfig `yaml:"local,omitempty"`
// External configures registry-backed shared cache.
External ExternalCacheConfig `yaml:"external,omitempty"`
// Cleanup is governance-owned host-hygiene policy — see HostCleanupConfig.
Cleanup HostCleanupConfig `yaml:"cleanup,omitempty"`
}
BuildCacheConfig defines the three-layer build cache subsystem. Mode selects the active planes. Advanced config underneath only when needed.
func DefaultBuildCacheConfig ¶ added in v0.5.0
func DefaultBuildCacheConfig() BuildCacheConfig
DefaultBuildCacheConfig returns baseline defaults. Mode is empty (inactive) — cleanup and cache only execute when mode is explicitly set. Governance presets should override enforcement and thresholds per runner class.
func (BuildCacheConfig) IsActive ¶ added in v0.5.0
func (c BuildCacheConfig) IsActive() bool
IsActive returns true if any cache mode is enabled.
type BuildCachePrunePolicy ¶ added in v0.5.0
type BuildCachePrunePolicy struct {
OlderThan string `yaml:"older_than,omitempty"` // e.g. "72h"
KeepStorage string `yaml:"keep_storage,omitempty"` // e.g. "20GB"
}
BuildCachePrunePolicy defines build cache pruning rules.
type BuildConfig ¶
type BuildConfig struct {
// ID is the unique identifier for this build, referenced by targets.
ID string `yaml:"id"`
// Kind is the build type. Determines which fields are valid.
// Supported: "docker", "binary", "command".
// - docker: build an OCI image
// - binary: build an executable via a language builder (opinionated inference)
// - command: run an arbitrary command in an image, capture typed outputs (the
// un-opinionated escape hatch; no inference). Prefer a `builder:` when
// one fits; reach for command only when none does.
Kind string `yaml:"kind"`
// SelectTags enables CLI filtering via --select.
SelectTags []string `yaml:"select_tags,omitempty"`
// Required means build failure is a hard pipeline fail. Default: true.
Required *bool `yaml:"required,omitempty"`
// BuildMode controls the build execution strategy.
// Supported: "" (standard), "crucible" (self-proving rebuild).
BuildMode string `yaml:"build_mode,omitempty"`
// DependsOn lists the nodes that must complete before this build runs. Entries
// are TYPED references: a bare id (or "build:<id>") is another BUILD; "scribe:<id>"
// is a scribe content item that must be rendered first (a build baking scribe
// output — e.g. a doc-site build consuming composed pages). Accepts a scalar or a
// sequence; a bare id stays a build ref, so existing `depends_on: x` is unchanged.
// Typed prefixes keep the build and scribe id spaces separate — no shared-uid rule.
DependsOn StringOrList `yaml:"depends_on,omitempty"`
// Dockerfile is the path to the Dockerfile. Default: auto-detect.
Dockerfile string `yaml:"dockerfile,omitempty"`
// Context is the Docker build context path. Default: "." (repo root).
Context string `yaml:"context,omitempty"`
// Target is the --target stage name for multi-stage builds.
Target string `yaml:"target,omitempty"`
// Platforms lists the target platforms. Default: [linux/{current_arch}].
Platforms []string `yaml:"platforms,omitempty"`
// BuildArgs are key-value pairs passed as --build-arg. Supports templates.
BuildArgs map[string]string `yaml:"build_args,omitempty"`
// Cache holds build cache settings.
Cache CacheConfig `yaml:"cache,omitempty"`
// Stage recycles a binary build's output into this docker build's context before
// buildx, so a copy-pre-built Dockerfile (COPY <name>) resolves — the compiled
// binary is reused, not recompiled inside the image.
Stage *StageConfig `yaml:"stage,omitempty"`
// Builder is the toolchain that interprets the build.
// Supported: "go", "rust", "node", "elixir", "dotnet", "c", "python", "jvm", "android"
// (authoritative list: validBuilders in enums.go). Future: "zig". Empty defaults to "go".
Builder string `yaml:"builder,omitempty"`
// Command is the builder subcommand (binary: e.g. "build") or the full command
// (kind: command). Accepts a scalar string or an argv sequence. Default: "build".
Command CommandSpec `yaml:"command,omitempty"`
// From is the source/input root or entry point.
// e.g., "./src/cli" (Go package), "./src/main.rs" (Rust).
From string `yaml:"from,omitempty"`
// Output is the artifact name. Windows platforms auto-append ".exe".
// Default: basename of From.
Output string `yaml:"output,omitempty"`
// Image is the container image a containerized build (builder: node, elixir) runs
// inside (with the repo mounted). Command runs in it; Output is the produced
// artifact (file or directory tree). Defaults per builder; override for the odd
// case (e.g. electronuserland/builder:wine, or an elixir+node image for Phoenix).
Image string `yaml:"image,omitempty"`
// Args are ordered raw arguments passed directly to the selected builder.
// For Go: raw args to "go build". For Rust: raw args to "cargo build".
// Supports template variables: {version}, {sha}, {sha:N}, {date}.
Args []string `yaml:"args,omitempty"`
// Env are build environment variables. e.g., {"CGO_ENABLED": "0"}
Env map[string]string `yaml:"env,omitempty"`
// Compress enables UPX compression on the output binary. Default: false.
Compress bool `yaml:"compress,omitempty"`
// Crucible holds crucible-specific configuration for binary builds.
Crucible *CrucibleConfig `yaml:"crucible,omitempty"`
// Outputs declares what the command produced and each output's artifact class.
Outputs []OutputSpec `yaml:"outputs,omitempty"`
}
BuildConfig defines a named build artifact. Each build has a unique ID (referenced by targets) and a kind that determines which fields are valid.
This is a discriminated union keyed by Kind — only fields relevant to the kind should be set. Validated at load time by v2 validation.
func (BuildConfig) BuildDeps ¶ added in v0.8.0
func (b BuildConfig) BuildDeps() []string
BuildDeps returns the BUILD ids this build depends on — the bare or "build:"- prefixed entries in depends_on, with the prefix stripped. Scribe deps are excluded.
func (BuildConfig) BuilderCommand ¶ added in v0.4.0
func (b BuildConfig) BuilderCommand() string
BuilderCommand returns the builder command, defaulting to "build".
func (BuildConfig) IsRequired ¶ added in v0.5.0
func (b BuildConfig) IsRequired() bool
IsRequired returns whether build failure is a hard pipeline fail. Default: true.
func (BuildConfig) OutputName ¶ added in v0.4.0
func (b BuildConfig) OutputName() string
OutputName returns the output artifact name, defaulting to basename of From.
func (BuildConfig) ScribeDeps ¶ added in v0.8.0
func (b BuildConfig) ScribeDeps() []string
ScribeDeps returns the scribe content ids this build consumes as inputs — the "scribe:"-prefixed entries in depends_on. These render before this build runs.
type BuilderConfig ¶ added in v0.5.0
type BuilderConfig struct {
// Backend pins the build backend. Default: "" (auto-detect).
// "buildkitd" → prefer persistent buildkitd, fail if unavailable.
// "dind" → use DinD only, ignore buildkitd even if available.
// "" → auto-detect: prefer buildkitd if available, fall back to DinD.
Backend string `yaml:"backend,omitempty"`
// Name is the buildx builder name. Default: "sf-builder".
Name string `yaml:"name,omitempty"`
// Driver is the buildx driver. Default: "docker-container".
Driver string `yaml:"driver,omitempty"`
// Context is the Docker context name for the builder endpoint. Default: "sf-context".
Context string `yaml:"context,omitempty"`
// Memory caps the builder container (e.g. "3g"), pinning memory-swap to the same
// value so the builder cannot swap. Unset derives it from the runner: total RAM
// minus a reserve that keeps the host alive — a build must never be able to
// livelock its own machine. Only applies to a builder StageFreight creates
// (docker-container driver); an external buildkitd owns its own limits.
Memory string `yaml:"memory,omitempty"`
}
BuilderConfig declares the buildx builder identity. The engine creates/bootstraps/narrates — this is just the declaration.
func (BuilderConfig) BuilderDriver ¶ added in v0.5.0
func (b BuilderConfig) BuilderDriver() string
BuilderDriver returns the driver, defaulting to "docker-container".
func (BuilderConfig) BuilderName ¶ added in v0.5.0
func (b BuilderConfig) BuilderName() string
BuilderName returns the builder name, defaulting to "sf-builder".
func (BuilderConfig) ContextName ¶ added in v0.5.0
func (b BuilderConfig) ContextName() string
ContextName returns the Docker context name, defaulting to "sf-context".
type CIConfig ¶ added in v0.6.0
type CIConfig struct {
// Image is the container image for all pipeline jobs.
// Required — render refuses to emit without it.
Image string `yaml:"image"`
// Forge names the forge whose CI skeleton this repo runs on, and therefore which
// pipeline file governance renders and distributes (gitlab → .gitlab-ci.yml,
// github → .github/workflows/stagefreight.yml, …). More than one may be listed —
// each writes its own file — for a repo genuinely wired to two CI systems.
//
// It is DECLARED, never inferred. The primary repo's forge is the obvious guess and
// it is wrong often enough to matter: a repo can be authoritative on one forge and
// run CI on another after replication — source on GitLab, Actions on the GitHub
// mirror. Guessing there writes a skeleton for a forge that never runs it while the
// one that does goes stale, surfacing as an unexplained "CI is stale" at audition.
//
// Empty means no CI file is rendered or distributed. That is deliberate: a repo that
// has not said where its CI runs gets nothing, rather than something plausible.
Forge []string `yaml:"forge,omitempty"`
// Routing declares per-phase runner placement requirements.
// The renderer lowers labels to forge-native primitives
// (GitLab: tags, GitHub/Gitea/Forgejo: runs-on).
Routing RoutingConfig `yaml:"routing,omitempty"`
}
CIConfig holds all pipeline-related configuration consumed by stagefreight ci render. One block, one concern.
type CacheConfig ¶
CacheConfig holds build cache settings.
type ClusterConfig ¶ added in v0.5.0
type ClusterConfig struct {
Name string
Endpoint string
Exposure ExposureRules
}
ClusterConfig identifies a Kubernetes cluster and how to connect to it. Built from a GitOpsCluster via Connection(); it is an internal descriptor, not a YAML shape. CA trust is resolved from environment variables at runtime:
- <NAME>_CA_FILE: path to CA certificate file
- <NAME>_CA_B64: base64-encoded CA certificate PEM
Name is uppercased with hyphens replaced by underscores for the env prefix.
type CommandSpec ¶ added in v0.7.0
type CommandSpec string
CommandSpec is a build command that accepts either a scalar shell string (`command: "go build"`) or a sequence / argv list (`command: [go, build]`), normalized to a single string for `sh -c`. The sequence form is shell-quoted so args with spaces survive. Used by binary builders (a subcommand) and kind: command (the full command).
func (*CommandSpec) UnmarshalYAML ¶ added in v0.7.0
func (c *CommandSpec) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML accepts a scalar or a sequence of strings.
type CommitConfig ¶
type CommitConfig struct {
Preset string `yaml:"preset,omitempty"`
DefaultType string `yaml:"default_type,omitempty"`
DefaultScope string `yaml:"default_scope,omitempty"`
SkipCI bool `yaml:"skip_ci,omitempty"`
Push bool `yaml:"push,omitempty"`
Conventional bool `yaml:"conventional"`
// Render controls commit rendering (default DefaultCommitPresentation; a
// partial render: block overlays those defaults).
Render CommitPresentation `yaml:"render,omitempty"`
Backend string `yaml:"backend,omitempty"`
Types []CommitType `yaml:"types,omitempty"`
}
CommitConfig holds configuration for the commit subsystem.
func DefaultCommitConfig ¶
func DefaultCommitConfig() CommitConfig
DefaultCommitConfig returns sensible defaults for commit configuration.
type CommitPresentation ¶ added in v0.5.0
type CommitPresentation struct {
PreserveRawSubject bool `yaml:"preserve_raw_subject"`
EnforceConventional bool `yaml:"enforce_conventional"`
}
CommitPresentation controls commit rendering (commit.render). Authoring-oriented: alias expansion and validation, NOT release-style uplift.
func DefaultCommitPresentation ¶ added in v0.8.0
func DefaultCommitPresentation() CommitPresentation
DefaultCommitPresentation is the default commit.render policy.
type CommitType ¶
type CommitType struct {
Key string `yaml:"key"`
Label string `yaml:"label"`
AliasFor string `yaml:"alias_for,omitempty"`
ForceBang bool `yaml:"force_bang,omitempty"`
}
CommitType defines a recognized commit type for conventional commits.
type CompiledPatterns ¶
CompiledPatterns holds pre-compiled include and exclude regex patterns. Avoids repeated regex compilation during planning and matching.
func CompilePatterns ¶
func CompilePatterns(patterns []string, policyMap map[string]string) (*CompiledPatterns, error)
CompilePatterns resolves pattern tokens against a policy map and compiles them into include/exclude regex groups. Discards warnings.
func CompilePatternsWithWarnings ¶
func CompilePatternsWithWarnings(patterns []string, policyMap map[string]string) (*CompiledPatterns, []string, error)
CompilePatternsWithWarnings resolves pattern tokens against a policy map, compiles them into include/exclude regex groups, and returns any warnings (e.g., typo detection for unknown policy names).
func (*CompiledPatterns) Match ¶
func (cp *CompiledPatterns) Match(value string) bool
Match evaluates the compiled patterns against a value. Exclude-first semantics: if any exclude matches, rejected. Empty include list with no excludes = pass (no constraints). Empty include list with only excludes = everything not excluded passes.
type Condition ¶
type Condition struct {
// Tag is a pattern matched against the git tag (CI_COMMIT_TAG).
// Only evaluated when a tag is present. Prefix with ! to negate.
Tag string `yaml:"tag,omitempty"`
// Branch is a pattern matched against the git branch (CI_COMMIT_BRANCH).
// Prefix with ! to negate.
Branch string `yaml:"branch,omitempty"`
}
Condition is the universal conditional rule primitive used across StageFreight. Every feature that has tag/branch-sensitive behavior uses this same structure.
Pattern syntax (applies to Tag, Branch, and any future filter fields):
"^main$" — regex match (default) "!^feature/.*" — negated regex (! prefix) "main" — literal match (no regex metacharacters) "!develop" — negated literal
Matching logic:
- Tag: tested against CI_COMMIT_TAG / git tag. Only evaluated when a tag is present.
- Branch: tested against CI_COMMIT_BRANCH / git branch.
- Multiple fields set: AND — all present fields must match.
- No fields set: catch-all (always matches).
Rules are always evaluated top-down, first match wins. CLI overrides take precedence.
type Config ¶
type Config struct {
// Version must be 1. The pre-version config was an unversioned alpha
// that never earned a schema number — this is the first stable schema.
Version int `yaml:"version"`
// Vars is a user-defined template variable dictionary.
// Referenced as {var:name} anywhere templates are resolved.
Vars map[string]string `yaml:"vars,omitempty"`
// Defaults is inert YAML anchor storage. StageFreight ignores this
// section entirely — it exists for users to define &anchors.
Defaults yaml.Node `yaml:"defaults,omitempty"`
// PresetSource is governance-distribution metadata: where a satellite's presets
// were frozen from (forge coords + pinned ref + cache policy). Written by
// `governance reconcile`; IGNORED at runtime today — the committed
// .stagefreight/preset-cache is authoritative — but declared so a governed config
// decodes under KnownFields(true). Consumed only if/when runtime pinned-external
// resolution is built.
PresetSource *PresetSource `yaml:"preset_source,omitempty"`
// Forges declares git hosts as an id→forge map (provider, URL, credentials).
Forges OrderedForges `yaml:"forges,omitempty"`
// Repos declares projects as an id→repo map. References forges by id. Has role.
Repos OrderedRepos `yaml:"repos,omitempty"`
// Registries declares OCI registry hosts as an id→registry map.
Registries OrderedRegistries `yaml:"registries,omitempty"`
// Orgs declares organization/owner identities as an id→org map (maintainer +
// aliases). Identity only — no forge, no credentials. Feeds {org.*} and, through
// surface default_paths, {path.*}. See docs/design/identity-model.md.
Orgs OrderedOrgs `yaml:"orgs,omitempty"`
// Metadata is this repo's identity/branding — the one block every consumer reads
// (org ref, title, names, scoped description/readme, topics, license, …). Feeds
// {metadata.*}. See docs/design/identity-model.md.
Metadata MetadataConfig `yaml:"metadata,omitempty"`
// SigningSetup is the signing block. Its Profiles field holds the named trust
// profiles (generic primitives), referenced per-target by signing_profile: <id>.
// "Releases require hardware" is project policy (the target's selection), never
// encoded in the framework.
SigningSetup SigningConfig `yaml:"signing,omitempty"`
// Git is the git: cluster and the single source for ref interpretation: named
// branch patterns (git.branches), tag patterns (git.tags), and versioning rules
// (git.versioning). Consumers read cfg.Git.Branches / cfg.Git.Tags /
// cfg.Git.Versioning.{BranchBuilds,NoLineage} directly — no translation layer.
Git GitConfig `yaml:"git,omitempty"`
// Builds defines named build artifacts as an id→build map.
Builds OrderedBuilds `yaml:"builds"`
// Targets defines distribution targets and side-effects. Declared under the
// publish: key as an id→target map (execution order preserved).
Targets OrderedTargets `yaml:"publish,omitempty"`
// Lint holds lint-specific configuration (unchanged from v1).
Lint LintConfig `yaml:"lint"`
// Security holds security scanning configuration (unchanged from v1).
Security SecurityConfig `yaml:"security"`
// Commit holds configuration for the commit subsystem.
Commit CommitConfig `yaml:"commit"`
// Dependency holds configuration for the dependency update subsystem.
Dependency DependencyConfig `yaml:"dependency"`
// LLMs is the model endpoint library (llms:): id → { provider, url, model,
// credentials }, referenced by type: llm stencils via llm: <id>.
LLMs OrderedLLMs `yaml:"llms,omitempty"`
// Stencils is the shared audience-text library: id → reusable markdown element
// with {…} variable fill, embeddable as {id} anywhere SF composes text (scribe
// file regions, narrate, release bodies). Presence-neutral (a shared library, not
// a phase). Consumers differ only by destination.
Stencils OrderedStencils `yaml:"stencils,omitempty"`
// Scribe places rendered stencils into repository files and commits them: files:
// (placement regions whose bodies reference stencils by {id}) + commit:.
// Presence-enabled (files/commit gate the stage).
Scribe ScribeConfig `yaml:"scribe"`
// Notifications sends a message when a run finishes: id → { provider, on, subject,
// body, … }. Flat, one entry per notification. subject/body accept {…} embeds; an
// omitted body defaults to the run's apex summary. Dispatched by the narrate phase.
Notifications OrderedNotifications `yaml:"notifications,omitempty"`
// Narrate is the stdout storytelling surface: announces: lists stencil ids rendered
// as structured-output cards at the end of the run (default: the built-in summary).
Narrate NarrateConfig `yaml:"narrate,omitempty"`
Test TestConfig `yaml:"test"`
// Manifest holds configuration for the manifest subsystem.
Manifest ManifestConfig `yaml:"manifest"`
// Release holds configuration for the release subsystem.
Release ReleaseConfig `yaml:"release"`
// CI holds all pipeline-related configuration consumed by ci render.
CI CIConfig `yaml:"ci"`
// Lifecycle defines the repository lifecycle mode (image, gitops, governance).
Lifecycle LifecycleConfig `yaml:"lifecycle"`
// Governance declares the control repo's governance profiles. It is
// PRESENCE-GATED, not mode-gated: the reconcile facet activates whenever
// governance.profiles is non-empty (like the ansible/gitops subsystems), so a
// control repo needs no lifecycle.mode: governance. A satellite instead carries
// governance.source (a pointer at its policy repo).
Governance GovernanceConfig `yaml:"governance"`
// GitOps defines the gitops lifecycle target clusters, keyed by cluster name.
GitOps OrderedClusters `yaml:"gitops,omitempty"`
// Ansible defines the ansible host-convergence subsystem. Presence-gated
// (any converge playbook activates it) and independent of lifecycle.mode.
Ansible AnsibleConfig `yaml:"ansible"`
// Docker defines configuration for the docker lifecycle mode.
Docker DockerLifecycleConfig `yaml:"docker"`
// BuildCache defines the build cache subsystem (local, shared, hybrid).
BuildCache BuildCacheConfig `yaml:"build_cache"`
// Glossary defines the repo's shared change-language model.
// Consumed by commit authoring, tag planning, and release rendering.
Glossary GlossaryConfig `yaml:"glossary"`
// Tag holds workflow defaults for the tag planner.
Tag TagConfig `yaml:"tagging"`
// Toolchains defines operator control over external tool resolution.
// Version pins, future retention policy, future trust settings.
Toolchains ToolchainSection `yaml:"toolchains,omitempty"`
}
Config is the top-level StageFreight v2 configuration.
func Load ¶
Load reads configuration from a YAML file. If path is empty, it tries the default file. Returns sensible defaults if the file doesn't exist. Discards validation warnings; use LoadWithWarnings for full diagnostics.
func LoadWithWarnings ¶
LoadWithWarnings reads configuration from a YAML file and returns validation warnings alongside the config. Thin wrapper over loadResolved — the single preset-resolving construction path (invariants.md §1); every runtime caller funnels through it.
func (*Config) ApplyStencilStoreDefaults ¶ added in v0.8.0
func (c *Config) ApplyStencilStoreDefaults()
ApplyStencilStoreDefaults derives Output = {store}/{id}.svg for badge stencils that don't set an explicit output path, so a badge stencil needs no per-item output: line. An explicit output: wins. Store comes from scribe.store (default DefaultScribeStore) — badge SVGs are a scribe-placed asset.
func (*Config) Mode ¶ added in v0.8.0
func (c *Config) Mode() LifecycleMode
Mode resolves this config's lifecycle mode for DISPATCH. An unknown mode falls back to the image fact-set — the same outcome the phase bodies' `default:` arm gives — because validation rejects unknown modes at load, so a dispatch-time lookup can safely treat anything unresolved as the build default.
func (*Config) StencilsByID ¶ added in v0.8.0
func (c *Config) StencilsByID() map[string]StencilDef
StencilsByID is the Config-level convenience over the stencil library.
func (*Config) WorktreeOutputs ¶ added in v0.7.0
func (c *Config) WorktreeOutputs() []WorktreeOutput
WorktreeOutputs returns every build output opted into the working tree (outputs[].worktree) across all builds. The runner materializes these at the start of Narrate; Perform's archive trigger uses them to know which build trees must cross to Narrate as transport artifacts.
type ConfigReport ¶ added in v0.6.0
type ConfigReport struct {
SourceFile string `json:"source_file"`
Presets []string `json:"presets,omitempty"`
Overrides int `json:"overrides,omitempty"`
Sections []SectionState `json:"sections,omitempty"`
SyncTopology *SyncTopology `json:"sync_topology,omitempty"`
VarsApplied int `json:"vars_applied,omitempty"`
Warnings []string `json:"warnings,omitempty"`
Status string `json:"status"` // "ok" | "partial" | "error"
Completeness string `json:"completeness"` // "complete" | "partial"
Error string `json:"error,omitempty"`
}
ConfigReport is the result of loading and resolving configuration. Surfaces the "Explain" layer of the resolution pipeline.
type ContainerPrunePolicy ¶ added in v0.5.0
type ContainerPrunePolicy struct {
Exited AgePruneRule `yaml:"exited,omitempty"`
}
ContainerPrunePolicy defines container pruning rules.
type CrucibleConfig ¶ added in v0.4.0
type CrucibleConfig struct {
// ToolchainImage is the pinned container image for pass-2 verification.
// e.g., "docker.io/library/golang:1.24-alpine"
ToolchainImage string `yaml:"toolchain_image,omitempty"`
}
CrucibleConfig holds crucible-specific build configuration.
type DependencyCIConfig ¶
type DependencyCIConfig struct {
Handoff DependencyHandoff `yaml:"handoff"` // default: continue
}
DependencyCIConfig controls CI-level behavior when deps creates a commit.
type DependencyCommitConfig ¶
type DependencyCommitConfig struct {
Enabled bool `yaml:"enabled"`
Type string `yaml:"type"`
Message string `yaml:"message"`
Push bool `yaml:"push"`
SkipCI bool `yaml:"skip_ci"`
Promotion DependencyCommitPromotion `yaml:"promotion"` // "direct" or "mr"
MR DependencyMRConfig `yaml:"mr"`
RunFrom RunFromConfig `yaml:"run_from,omitempty"` // gate mutation to declared origin
}
DependencyCommitConfig controls auto-commit behavior for dependency updates.
type DependencyCommitPromotion ¶ added in v0.4.0
type DependencyCommitPromotion string
DependencyCommitPromotion controls how dependency commits reach the target branch.
const ( PromotionDirect DependencyCommitPromotion = "direct" // push to current branch (existing behavior) PromotionMR DependencyCommitPromotion = "mr" // push to unique bot branch, open merge request )
type DependencyConfig ¶
type DependencyConfig struct {
Preset string `yaml:"preset,omitempty"`
Enabled bool `yaml:"enabled"`
Output string `yaml:"output"`
Scope DependencyScopeConfig `yaml:"scope"`
Commit DependencyCommitConfig `yaml:"commit"`
CI DependencyCIConfig `yaml:"ci"`
Ignore []DependencyIgnore `yaml:"ignore,omitempty"`
// Remediate controls whether the update pass PATCHES eligible dependencies
// (true, default — fix-forward) or only evaluates them without changing
// anything (false). It is the module's remediation stage, orthogonal to
// fail_on (the policy stage).
Remediate *bool `yaml:"remediate,omitempty"`
// Outdated gates on how far a dependency has fallen behind — an update-MAGNITUDE
// policy, not a severity one. Vulnerability severity has exactly one authority,
// security.fail_on; duplicating that vocabulary here made two places disagree
// about the same question.
Outdated OutdatedGate `yaml:"outdated,omitempty"`
// Policy is the freshness SCOPE — which non-vulnerable dependencies to pursue:
// "all" (default — every dep to its latest eligible) or "security" (only
// vulnerable deps; leave everything else where it is). A known vulnerability is
// a floor, remediated under EVERY policy — Policy only governs freshness of
// NON-vulnerable deps. Empty defaults to "all" (today's audition behavior).
Policy string `yaml:"policy,omitempty"`
// MaxUpdate is the update-type CEILING — how far a dependency may move:
// "major" (allow the ecosystem's own maximum), "minor" (n.x.n — lock the major,
// allow minor+patch), or "patch" (n.n.x — lock major and minor, allow patch
// only). Empty defaults to "major" — a NO-OP that imposes no ceiling beyond each
// ecosystem's native compatibility model (cargo/docker still hold out-of-range
// majors via their `^`/tag-line semantics; gomod/github-release/toolchain retain
// their prior auto-apply). Setting "minor"/"patch" is an explicit opt-in to hold
// majors (and minors). A security fix is applied even if it exceeds the ceiling
// (remediation floor).
MaxUpdate string `yaml:"max_update,omitempty"`
// MinReleaseAge is the supply-chain COOLDOWN: a release younger than this is
// not recommended (freshness) nor applied (deps) — dodging the window in which
// a compromised or yanked release is briefly live. Accepts durations like
// "3d", "72h". Owned here as a supply-chain policy; the freshness lint module
// reads the SAME value so its recommendations match what deps will apply.
// Empty falls back to lint.modules.freshness.options.min_release_age (its
// historical home) for back-compat, then to disabled.
MinReleaseAge string `yaml:"min_release_age,omitempty"`
}
DependencyConfig holds configuration for the dependency update subsystem.
func DefaultDependencyConfig ¶
func DefaultDependencyConfig() DependencyConfig
DefaultDependencyConfig returns sensible defaults for dependency management.
func (DependencyConfig) EffectiveMaxUpdate ¶ added in v0.7.0
func (c DependencyConfig) EffectiveMaxUpdate() string
EffectiveMaxUpdate resolves the update-type ceiling, defaulting to "major" — a no-op that preserves each ecosystem's native behavior (holding majors is an explicit opt-in, never a silent default). Lowercased "major" | "minor" | "patch".
func (DependencyConfig) EffectivePolicy ¶ added in v0.7.0
func (c DependencyConfig) EffectivePolicy() string
EffectivePolicy resolves the freshness scope, defaulting to "all". Lowercased "all" | "security".
func (DependencyConfig) RemediateEnabled ¶ added in v0.7.0
func (c DependencyConfig) RemediateEnabled() bool
RemediateEnabled reports whether the update pass patches eligible dependencies. Default: true (fix-forward).
type DependencyHandoff ¶
type DependencyHandoff string
DependencyHandoff controls what happens when dependency repair creates a new commit.
- "continue" — advisory only, current pipeline continues regardless
- "restart_pipeline" — request pipeline rerun on repaired revision; downstream shipping stops
- "fail" — fail hard if repair was needed but couldn't be handed off
const ( HandoffContinue DependencyHandoff = "continue" HandoffRestartPipeline DependencyHandoff = "restart_pipeline" HandoffFail DependencyHandoff = "fail" )
type DependencyIgnore ¶ added in v0.7.0
type DependencyIgnore struct {
ID string `yaml:"id"` // e.g. "GHSA-xxxx-yyyy-zzzz", "GO-2026-1234"
Reason string `yaml:"reason,omitempty"` // why this risk is carried
Until string `yaml:"until,omitempty"` // YYYY-MM-DD; past this date the ignore lapses
}
DependencyIgnore suppresses a specific security advisory from remediation — an accepted-risk or false-positive decision. Keyed by advisory ID (the same `ignore` term osv-scanner/Trivy/Grype/Dependabot use), with a required reason and an expiry after which it lapses and the advisory re-surfaces.
type DependencyMRConfig ¶ added in v0.4.0
type DependencyMRConfig struct {
BranchPrefix string `yaml:"branch_prefix"` // default: "stagefreight/deps"
TargetBranch string `yaml:"target_branch"` // default: "" (CI default branch)
}
DependencyMRConfig controls merge request creation for promotion: mr.
type DependencyScopeConfig ¶
type DependencyScopeConfig struct {
GoModules bool `yaml:"go_modules"`
DockerfileEnv bool `yaml:"dockerfile_env"` // umbrella for docker-image + github-release
}
DependencyScopeConfig controls which dependency ecosystems are managed.
func (DependencyScopeConfig) ScopeToEcosystems ¶
func (s DependencyScopeConfig) ScopeToEcosystems() []string
ScopeToEcosystems converts scope booleans to ecosystem filter strings compatible with dependency.UpdateConfig.Ecosystems. Returns nil (all ecosystems) if all scopes are enabled.
type DetailRule ¶
type DetailRule struct {
Condition `yaml:",inline"`
// Detail is the detail level to use when this rule matches.
// Values: "none", "counts", "detailed", "full".
Detail string `yaml:"detail"`
}
DetailRule is a conditional override for security detail level in release notes. Embeds Condition for standard tag/branch pattern matching.
type DockerDriftPolicy ¶ added in v0.5.0
type DockerDriftPolicy struct {
Tier2Action string `yaml:"tier2_action"` // report | reconcile (default: report)
OrphanAction string `yaml:"orphan_action"` // report | down | prune (default: report)
OrphanThreshold int `yaml:"orphan_threshold"` // block if more than N orphans (default: 5)
PruneRequiresConfirmation bool `yaml:"prune_requires_confirmation"` // require --force for prune (default: true)
}
DockerDriftPolicy configures drift detection behavior.
type DockerIaCConfig ¶ added in v0.5.0
type DockerIaCConfig struct {
// Path is the IaC directory relative to repo root (default: "docker-compose").
Path string `yaml:"path"`
}
DockerIaCConfig defines the IaC directory layout.
type DockerLifecycleConfig ¶ added in v0.5.0
type DockerLifecycleConfig struct {
Preset string `yaml:"preset,omitempty"`
// Backend selects the Docker execution engine (e.g. "compose").
Backend string `yaml:"backend"`
// Targets defines how reconciliation targets are resolved.
Targets DockerTargetsConfig `yaml:"targets"`
// IaC defines the Infrastructure as Code directory layout.
IaC DockerIaCConfig `yaml:"iac"`
// Secrets defines the secrets decryption provider.
Secrets DockerSecretsConfig `yaml:"secrets"`
// Drift defines drift detection and reconciliation policy.
Drift DockerDriftPolicy `yaml:"drift"`
}
DockerLifecycleConfig defines configuration for the docker lifecycle mode. This is Docker lifecycle orchestration, not docker-compose wrapping.
func DefaultDockerLifecycleConfig ¶ added in v0.5.0
func DefaultDockerLifecycleConfig() DockerLifecycleConfig
DefaultDockerLifecycleConfig returns sensible defaults.
type DockerSecretsConfig ¶ added in v0.5.0
type DockerSecretsConfig struct {
// Provider selects the secrets backend (e.g. "sops", "vault", "infisical").
Provider string `yaml:"provider"`
}
DockerSecretsConfig defines the secrets provider.
type DockerTargetSelector ¶ added in v0.5.0
type DockerTargetSelector struct {
Groups []string `yaml:"groups"`
}
DockerTargetSelector declares eligibility via existing inventory groups. Group-based initially. Richer selectors deferred until groups become insufficient.
type DockerTargetsConfig ¶ added in v0.5.0
type DockerTargetsConfig struct {
// Source is the inventory adapter (e.g. "ansible").
Source string `yaml:"source"`
// Inventory is the path to the inventory file (relative to repo root).
Inventory string `yaml:"inventory"`
// Selector declares which hosts from inventory are eligible.
Selector DockerTargetSelector `yaml:"selector"`
}
DockerTargetsConfig defines target resolution for Docker reconciliation.
type ExposureRule ¶ added in v0.5.0
type ExposureRule struct {
Level string `yaml:"level"` // internet | intranet | cluster
Endpoints []string `yaml:"endpoints"` // ip:port (highest precedence)
Gateways []string `yaml:"gateways"`
CIDRs []string `yaml:"cidrs"`
Ports []int `yaml:"ports"` // AND with CIDRs (empty = any port)
ServiceTypes []string `yaml:"service_types"` // ClusterIP | NodePort | LoadBalancer
}
ExposureRule classifies endpoints into exposure levels. Match fields are AND within a rule (CIDR AND port if both specified).
type ExposureRules ¶ added in v0.5.0
type ExposureRules struct {
Rules []ExposureRule `yaml:"rules"`
}
ExposureRules defines rule-based endpoint exposure classification. Rules are evaluated by precedence: endpoint > gateway > CIDR > service type. Conflicting equal-precedence rules → unknown. Never first-match-wins.
func (*ExposureRules) UnmarshalYAML ¶ added in v0.10.0
func (e *ExposureRules) UnmarshalYAML(n *yaml.Node) error
UnmarshalYAML accepts both the flat list form (exposure: [ -level: … ]) and the nested map form (exposure: {rules: [ … ]}). Rules is the only field, so the flat list is the canonical shape; the map form stays accepted for compatibility.
type ExternalCacheConfig ¶ added in v0.5.0
type ExternalCacheConfig struct {
// Registry references a registries[].id. Its URL + default_path locate the cache.
Registry string `yaml:"registry,omitempty"`
// Path is appended to the registry URL: <registry-url>/<path>/<repo>/<branch>.
Path string `yaml:"path,omitempty"`
// Fallback is the read-only fallback branch ref (e.g. "default", "main").
// Never written to unless current ref equals fallback.
Fallback string `yaml:"fallback,omitempty"`
// Mode is the BuildKit cache mode (e.g. "max", "min"). Default: "max".
Mode string `yaml:"mode,omitempty"`
// Retention defines when stale external cache refs are pruned.
Retention ExternalRetention `yaml:"retention,omitempty"`
}
ExternalCacheConfig defines registry-backed shared cache. References a registries[].id directly — no publish-target indirection.
type ExternalRetention ¶ added in v0.5.0
type ExternalRetention struct {
MaxRefs int `yaml:"max_refs,omitempty"` // max branch cache refs per repo
StaleAge string `yaml:"stale_age,omitempty"` // prune refs for dead/merged branches
}
ExternalRetention defines external cache ref lifecycle.
type FacetSpec ¶ added in v0.8.0
type FacetSpec struct {
Scope string `yaml:"scope,omitempty"` // "current" | "all" (exact expands here)
Prune bool `yaml:"prune,omitempty"` // delete target refs/releases absent on source
Force bool `yaml:"force,omitempty"` // refs only: overwrite a DIVERGED mirror ref (default off = keep-divergent)
Drafts bool `yaml:"drafts,omitempty"` // releases only: carry unpublished drafts
Only []string `yaml:"only,omitempty"` // releases only: restrict to these tag-sources
Match string `yaml:"match,omitempty"` // glob filter on ref/tag name
Assets string `yaml:"assets,omitempty"` // releases only: "" | "true" | "false" | "link"
}
FacetSpec is the resolved replication spec for one facet. A nil *FacetSpec on SyncConfig means the facet is not synced.
func (*FacetSpec) IsAll ¶ added in v0.8.0
IsAll reports scope: all — replicate every ref of the facet.
type FileDef ¶ added in v0.8.0
type FileDef struct {
ID string `yaml:"-"` // set from the files map key
File string `yaml:"file"`
LinkBase string `yaml:"link_base,omitempty"`
Between [2]string `yaml:"between,omitempty"`
Inline bool `yaml:"inline,omitempty"` // items sugar: render side-by-side
Items []string `yaml:"items,omitempty"` // stencil ids (+ "br"); sugar for a body
Body string `yaml:"body,omitempty"` // freeform markdown with {id} embeds
}
FileDef is one placement region (scribe.files[id]): a marked span in a file and the markdown placed into it. body: is freeform markdown with {id} stencil embeds (+ {#if}); items: is sugar for a body (a row of stencils, "br" for a row break, inline: for side-by-side). One or the other — body: wins when both are set.
type FilterConfig ¶ added in v0.5.0
type FilterConfig struct {
Summary SummaryFilter `yaml:"summary"`
Trailers TrailerFilter `yaml:"trailers"`
NormalizeWhitespace bool `yaml:"normalize_whitespace"`
}
FilterConfig defines sanitization rules for change summaries.
type ForgeConfig ¶ added in v0.6.0
type ForgeConfig struct {
ID string `yaml:"id"` // unique identifier (e.g., "prplanit-gitlab")
Provider string `yaml:"provider"` // gitlab, github, gitea
URL string `yaml:"url"` // base URL (e.g., "https://gitlab.prplanit.com")
Credentials string `yaml:"credentials,omitempty"` // env var prefix for token resolution
DefaultPath string `yaml:"default_path,omitempty"` // default project path template (e.g. "{org}/{repo}"), for {path.<id>}
}
ForgeConfig declares a git host. Declared once, referenced by repos. A forge is an identity — provider type, base URL, credentials.
func FindForgeByID ¶ added in v0.6.0
func FindForgeByID(forges []ForgeConfig, id string) *ForgeConfig
FindForgeByID returns the forge with the given id, or nil.
func ForgeForURL ¶ added in v0.9.0
func ForgeForURL(remoteURL string, forges []ForgeConfig, vars map[string]string) *ForgeConfig
ForgeForURL returns the configured forge whose host OWNS remoteURL's host, or nil when no configured forge matches. Matching is EXACT on the normalized hostname — never a prefix or substring compare — so a credential can only ever be selected for a host its forge actually claims. A forge URL's {var:...} placeholders resolve first. A nil result means "no configured forge owns this host": the caller must fall back to anonymous, so a token is never sent to an unclaimed host.
type Gate ¶ added in v0.7.0
type Gate string
Gate is the declarative lifecycle consequence of a test suite's failure.
It is a typed policy value, decoded once at the config boundary so internal comparisons never use raw string literals. v1 implements `perform` (default) and `advisory`; `publish` is reserved (see the test-subsystem plan) — the "build locally but deny distribution" tier arrives with the finer authorizePhase rail when a suite actually needs it.
const ( // GatePerform: a failed suite fails the audition exit code, which withholds // the cistate artifact and halts perform + everything downstream (only narrate // runs) — identical to how a lint critical gates today. This is the default. GatePerform Gate = "perform" // GateAdvisory: the suite runs and reports, but never affects the audition exit // code, so the pipeline ships regardless. GateAdvisory Gate = "advisory" // GatePublish: reserved (v2) — build the artifact but deny distribution. GatePublish Gate = "publish" )
type GitConfig ¶ added in v0.8.0
type GitConfig struct {
// Branches maps a matcher name to a regex.
Branches map[string]string `yaml:"branches,omitempty"`
// Tags maps a tag-source name to its pattern.
Tags OrderedTagSources `yaml:"tags,omitempty"`
// Versioning holds the derivation rules that consume the patterns above.
Versioning GitVersioning `yaml:"versioning,omitempty"`
}
GitConfig is the git: cluster — how the engine interprets a ref into named branch/tag patterns and the versions they imply. It is the SINGLE source: consumers read cfg.Git.Branches / cfg.Git.Tags / cfg.Git.Versioning directly — no translation layer, no separate Matchers/Versioning types.
type GitOpsCluster ¶ added in v0.10.0
type GitOpsCluster struct {
Name string `yaml:"-"` // from the map key
Preset string `yaml:"preset,omitempty"`
// Backend selects the GitOps reconciliation backend (e.g. "flux", "argo").
Backend string `yaml:"backend"`
// Endpoint is the cluster API server URL (e.g. https://host:6443).
Endpoint string `yaml:"endpoint"`
// Exposure classifies endpoint reachability (rule-based).
Exposure ExposureRules `yaml:"exposure"`
// OIDC defines authentication configuration for the cluster.
OIDC OIDCConfig `yaml:"oidc"`
}
GitOpsCluster is one gitops target cluster, keyed by its name in the gitops: map.
func (GitOpsCluster) Connection ¶ added in v0.10.0
func (c GitOpsCluster) Connection() ClusterConfig
Connection returns the connection descriptor the k8s/gitops packages consume.
type GitVersioning ¶ added in v0.8.0
type GitVersioning struct {
BranchBuilds OrderedBranchBuilds `yaml:"branch_builds,omitempty"`
NoLineage NoLineageConfig `yaml:"no_lineage,omitempty"`
}
GitVersioning is git.versioning — branch_builds + no_lineage (tag patterns moved up to git.tags).
type GlossaryConfig ¶ added in v0.5.0
type GlossaryConfig struct {
Preset string `yaml:"preset,omitempty"`
Types map[string]GlossaryType `yaml:"types"`
Breaking BreakingConfig `yaml:"breaking"`
Filters FilterConfig `yaml:"filters"`
Rewrites RewriteConfig `yaml:"rewrites"`
Render RenderConfig `yaml:"render"`
}
GlossaryConfig defines the repo's shared change-language model. Consumed by commit authoring, tag planning, and release rendering.
func DefaultGlossaryConfig ¶ added in v0.5.0
func DefaultGlossaryConfig() GlossaryConfig
DefaultGlossaryConfig returns sensible defaults for the glossary.
type GlossaryType ¶ added in v0.5.0
type GlossaryType struct {
Aliases []string `yaml:"aliases,omitempty"`
CanonicalAs string `yaml:"canonical_as,omitempty"` // normalize to this type (e.g., deps → chore)
Priority int `yaml:"priority"`
ReleaseVisible bool `yaml:"release_visible"`
}
GlossaryType defines a single change type's semantics.
type GovernanceConfig ¶ added in v0.5.0
type GovernanceConfig struct {
Profiles OrderedGovProfiles `yaml:"profiles"`
}
GovernanceConfig declares governance profiles for the control repo. Presence of profiles activates governance reconcile (presence-gated like ansible/gitops). Assets (CI skeletons, settings files, etc.) are declared inside each profile's stagefreight config as assets: entries — no separate skeleton construct.
type GovernanceProfile ¶ added in v0.10.0
type GovernanceProfile struct {
ID string `yaml:"-"` // from the profiles: map key
Repos map[string]any `yaml:"repos,omitempty"` // the location-anchored catalog (raw here)
Config map[string]any `yaml:"config,omitempty"` // the profile's shared StageFreight config
Credentials string `yaml:"credentials,omitempty"` // env var prefix for the write token
}
GovernanceProfile is one profile (config-side view). Repos and Config are raw maps — config only checks presence; the governance package owns the rich catalog shape.
type HostCleanupConfig ¶ added in v0.5.0
type HostCleanupConfig struct {
// Enabled controls whether cleanup runs. Independent of cache mode.
Enabled bool `yaml:"enabled,omitempty"`
// Enforcement controls what happens when cleanup cannot execute.
// best_effort: continue + structured warning.
// required: fail build immediately.
Enforcement string `yaml:"enforcement,omitempty"`
// Protect defines what is never pruned.
Protect ProtectionPolicy `yaml:"protect,omitempty"`
// Prune defines what is eligible for removal.
Prune PrunePolicy `yaml:"prune,omitempty"`
}
HostCleanupConfig defines host hygiene — classification-first pruning. Not cache — residue cleanup. Object classes match DD-UI's operation types.
Governance-owned policy, currently INACTIVE: the legacy executor was removed with the standalone build pipeline. Retained pending a perform-phase consumer.
type IDMap ¶ added in v0.9.0
type IDMap interface {
// contains filtered or unexported methods
}
IDMap is the marker every Ordered* id→entry map type implements — the compile-checked contract that the type is a Go slice DECODING as a YAML map keyed by entry id. Consumers that must know the YAML shape (the docs generator renders map form, never "- id:" list form) detect it through this interface instead of naming conventions.
type ImageProtection ¶ added in v0.5.0
type ImageProtection struct {
Refs []string `yaml:"refs,omitempty"` // glob patterns
}
ImageProtection defines which images are protected from pruning.
type ImagePrunePolicy ¶ added in v0.5.0
type ImagePrunePolicy struct {
Dangling AgePruneRule `yaml:"dangling,omitempty"`
Unreferenced AgePruneRule `yaml:"unreferenced,omitempty"`
// Refs is the operator's scoped ADOPTION list: third-party image streams
// (matched by the shared retention-grammar template syntax) that the operator
// explicitly grants a lifecycle — e.g. a CI base image pulled into the dind.
// Each entry carries its own retention rules (keep_last / max_age / …), the same
// RetentionRef grammar used everywhere retention appears. Nothing outside this
// list (or SF's own provenance) is ever image-pruned; this is an authorization,
// not a confidence judgment.
Refs []RetentionRef `yaml:"refs,omitempty"`
}
ImagePrunePolicy defines image pruning rules by class.
type KMSTrust ¶ added in v0.7.0
type KMSTrust struct {
Ref string `yaml:"ref"`
}
KMSTrust is a LOGICAL key ref (e.g. "release-signing-key"), bound to a concrete URI only at render time — never a cosign URI, so policy stays provider-portable.
type KeyTrust ¶ added in v0.7.0
type KeyTrust struct {
Ref string `yaml:"ref"`
}
KeyTrust is a key reference — "path" or "env:VAR". A reference, not a mechanism.
type LLMConfig ¶ added in v0.8.0
type LLMConfig struct {
ID string `yaml:"-"` // the map key ({llm: <id>} reference target)
Provider string `yaml:"provider"` // ollama (openai | anthropic | claude-agent reserved)
URL string `yaml:"url,omitempty"` // ollama: server base URL
Model string `yaml:"model,omitempty"` // model name/tag
Credentials string `yaml:"credentials,omitempty"` // env prefix for hosted providers
}
LLMConfig is one entry in the top-level llms: block — a model endpoint library, sibling of forges:/registries:. It earns library status because the alternative is endpoints and credentials leaking into stencils: (an AI stencil references a backend by id — `llm: local` — and stays pure composition). Provider is the engine axis: ollama ships first; openai/anthropic/claude-agent slot in behind the same shape (engine additions, zero reshape).
type LifecycleConfig ¶ added in v0.5.0
type LifecycleConfig struct {
// Preset references an external lifecycle fragment to inherit (the generic
// preset: fragment-include mechanism — resolved and deep-merged before parse).
Preset string `yaml:"preset,omitempty"`
// Mode selects the phase graph. Empty defaults to image.
// image — build → review → publish image pipeline (the default)
// docker — read-only Docker plan/reconcile (dry-run)
// gitops — validate + reconcile Flux manifests
// governance — governance control-repo reconcile
Mode string `yaml:"mode"`
}
LifecycleConfig selects the repository lifecycle mode — the phase graph the pipeline runs. Mode is the single most significant orchestration choice: review and publish are image-only; the other modes mark them not_applicable.
type LifecycleMode ¶ added in v0.8.0
type LifecycleMode struct {
// Name is the canonical (lowercased) mode identifier.
Name string
// PhaseReconcile reports whether the perform/audition/review/publish phase
// BODIES reconcile for this mode instead of build/review/publish. True for
// gitops+governance. False for image (build) and docker — docker reconciles
// via the `docker`/`reconcile` CLI (RunLifecycle), not the CI phase bodies.
PhaseReconcile bool
// Backend returns the RunLifecycle backend name for this mode, or nil when the
// mode has no RunLifecycle backend: image (builds via the CI pipeline) and
// governance (dispatched by its own subsystem, executeGovernanceReconcile —
// it never reaches RunLifecycle).
Backend func(*Config) string
}
LifecycleMode is the fact-set for one mode.
func LookupMode ¶ added in v0.8.0
func LookupMode(raw string) (LifecycleMode, bool)
LookupMode canonicalizes a raw lifecycle.mode string (lowercased, trimmed) and resolves its fact-set. Empty ≡ image (the live default the phase bodies apply via their `default:` arm). ok=false for an unknown mode — the validator uses this to reject typos.
type LintCacheConfig ¶ added in v0.5.0
type LintCacheConfig struct {
MaxAge string `yaml:"max_age,omitempty"` // evict entries not hit in this duration (e.g. "7d")
MaxSize string `yaml:"max_size,omitempty"` // evict oldest entries when cache exceeds this (e.g. "100MB")
}
LintCacheConfig controls lint result cache lifecycle. Content-addressed caches grow monotonically — every file edit creates a new entry. Without eviction, cache grows unbounded.
type LintConfig ¶
type LintConfig struct {
Preset string `yaml:"preset,omitempty"`
Level Level `yaml:"level"`
CacheDir string `yaml:"cache_dir"`
TargetBranch string `yaml:"target_branch"`
Exclude []string `yaml:"exclude"`
Modules map[string]ModuleConfig `yaml:"modules"`
Provenance ProvenanceConfig `yaml:"provenance,omitempty"`
Remediation RemediationConfig `yaml:"remediation,omitempty"`
Cache LintCacheConfig `yaml:"cache,omitempty"`
// FailOn is the DIAGNOSTIC-IMPORTANCE threshold at or above which a lint
// finding blocks the build: "critical" | "warning" | "info" | "off". This is
// lint's OWN ordered vocabulary (info < warning < critical) — deliberately NOT
// the vulnerability severity scale; a lint warning and a CVSS High are
// incomparable. Empty defaults to "critical" (today's behavior: only critical
// findings block). Note this is a SECOND control axis on top of each module's
// own severity: raising fail_on reclassifies lower-importance findings from
// other lint modules as blocking too.
FailOn string `yaml:"fail_on,omitempty"`
}
LintConfig holds lint-specific configuration.
func DefaultLintConfig ¶
func DefaultLintConfig() LintConfig
DefaultLintConfig returns production defaults.
func (LintConfig) EffectiveFailOn ¶ added in v0.7.0
func (c LintConfig) EffectiveFailOn() string
EffectiveFailOn resolves the lint gate threshold, defaulting to "critical" (today's behavior). Returns a lowercased "critical" | "warning" | "info" | "off". The lint package maps this onto its Severity tiers.
type LocalCacheConfig ¶ added in v0.5.0
type LocalCacheConfig struct {
Path string `yaml:"path,omitempty"` // override local cache root (default: /stagefreight/cache/buildkit)
Retention LocalRetention `yaml:"retention,omitempty"`
}
LocalCacheConfig defines bounded local BuildKit cache. Default path: /stagefreight/cache/buildkit (persistent runtime root). Override via Path field for non-standard mounts.
type LocalRetention ¶ added in v0.5.0
type LocalRetention struct {
MaxAge string `yaml:"max_age,omitempty"` // e.g. "7d"
MaxSize string `yaml:"max_size,omitempty"` // e.g. "15GB"
}
LocalRetention defines what local cache is allowed to exist.
type ManifestConfig ¶ added in v0.3.2
type ManifestConfig struct {
Preset string `yaml:"preset,omitempty"`
// Enabled controls whether manifest generation is active (default: false).
Enabled bool `yaml:"enabled"`
// Mode controls where the manifest is stored.
// ephemeral: temp location, use during run, discard after.
// workspace: generate to .stagefreight/manifests/, don't auto-commit.
// commit: generate and include in docs commit.
// publish: generate and export as release asset / CI artifact.
Mode string `yaml:"mode,omitempty"`
// OutputDir is the output directory for manifest files.
// Default: .stagefreight/manifests
OutputDir string `yaml:"output_dir,omitempty"`
}
ManifestConfig holds configuration for the manifest subsystem.
func DefaultManifestConfig ¶ added in v0.3.2
func DefaultManifestConfig() ManifestConfig
DefaultManifestConfig returns sensible defaults for manifest generation.
type MatchResult ¶ added in v0.7.0
MatchResult is the outcome of a target eligibility check: whether the target is eligible for the current CI context and, when it is not, a human-readable reason coupled to the decision. Narration reads Reason directly, so the explanation can never drift from the matcher logic that produced it.
func NotificationEligibility ¶ added in v0.8.0
func NotificationEligibility(when WhenConditions, outcome, event, branch, tag, forge string, tagPolicies, branchPolicies map[string]string) MatchResult
NotificationEligibility interprets a notification's when: — the SAME grammar as publish targets (events/branches/git_tags/forges, OR over condition-sets) plus the outcomes: dimension. Lives here, in the one when: interpreter, per the eligibility-routing invariant. outcome is the run's word: success | failure | warning (unknown matches only an empty outcomes:).
func TargetEligibility ¶ added in v0.7.0
func TargetEligibility(t TargetConfig, event, branch, tag, forge string, tagPolicies, branchPolicies map[string]string) MatchResult
TargetEligibility is the single authoritative interpretation of a target's when: conditions (events, then git_tags, then branches), returning the decision and — on rejection — the coupled reason.
INVARIANT: every capability (docker, binary archives, release, retention, sync, and every future distribution capability) MUST route its when: interpretation through TargetEligibility/TargetMatches. Capability code must NOT inspect t.When.Events / t.When.Branches / t.When.GitTags directly. A new eligibility dimension is added here, to the framework — never bolted onto a caller. (This is the engine that replaced the old per-capability gates.)
tagPolicies/branchPolicies resolve named patterns (versioning.tag_sources, matchers.branches); inline "re:" and "!" negation are handled by ResolvePatterns. Empty conditions never restrict.
type MergeEntry ¶ added in v0.6.0
type MergeEntry struct {
Path string // dot-path (e.g., "security.sbom")
Source string // "managed", "local", "preset:preset/security.yml"
SourceRef string // "PrPlanIT/MaintenancePolicy@v1.0.0" for presets
Layer int // resolution depth (0=innermost preset, N=outermost, N+1=managed, N+2=local)
Operation string // "set", "override", "merge", "replace"
Value any
Overridden bool
OverriddenBy string
}
MergeEntry records the provenance of a single config value.
func ResolvePresets ¶ added in v0.6.0
func ResolvePresets(root *yaml.Node, loader PresetLoader, sourceRef, sourcePath string, depth int, seen map[string]bool) (*yaml.Node, []MergeEntry, error)
ResolvePresets walks a config node, finds all preset:/presets: references, loads the preset files, validates the single-key invariant, and merges — order-preserving. Recursive: presets may reference other presets (depth-first). sourceRef is the repo identity; sourcePath is the current file. Returns the resolved node + provenance.
type MergeTrace ¶ added in v0.6.0
type MergeTrace struct {
Entries []MergeEntry
}
MergeTrace records how each config value was resolved.
type MetadataConfig ¶ added in v0.10.0
type MetadataConfig struct {
// Org references an orgs: entry by id (the repo's owner). May be derived from the
// primary repo location instead of declared.
Org string `yaml:"org,omitempty"`
// Title is the human display name (e.g. "ARK Server"); defaults to the slug.
Title string `yaml:"title,omitempty"`
// Names overrides the repo's PATH name per surface (default = slug), e.g.
// { dockerhub: arkserver, github: SteamCMD }.
Names map[string]string `yaml:"names,omitempty"`
// Description is scoped: the default may be a tiered StringOrList (fit-picked across
// un-named surfaces); a named surface takes a single string.
Description Scoped[StringOrList] `yaml:"description,omitempty"`
// Readme is the source doc pushed to registry overviews / forge About, scoped:
// a default path or per-surface paths. Defaults to the auto-detected README.
Readme Scoped[string] `yaml:"readme,omitempty"`
Topics []string `yaml:"topics,omitempty"`
License string `yaml:"license,omitempty"`
Category string `yaml:"category,omitempty"`
// Website / DocsURL are optional and only for a genuinely SEPARATE site (product
// page / hosted docs) — never the repo URL, which is a coordinate ({path.<forge>}).
Website string `yaml:"website,omitempty"`
DocsURL string `yaml:"docs_url,omitempty"`
Icon string `yaml:"icon,omitempty"`
// Labels is the open forward-compat escape hatch (OCI-annotation style) for
// metadata the schema does not model — funding, support/changelog URLs, deprecation.
// It is NEVER a back door for a typed field above.
Labels map[string]string `yaml:"labels,omitempty"`
}
MetadataConfig is the metadata: block — a repo's identity/branding, the one place every consumer reads. The load-bearing fields (org, license, names) feed coordinates/module/license; the rest is branding, distributed for free. Feeds the {metadata.*} facts. See docs/design/identity-model.md.
This is a single block (the CURRENT repo's identity). The governance catalog's per- repo entries reuse the same shape, keyed by id — that lands with the governance work.
type MirrorSync ¶ added in v0.8.0
type MirrorSync struct {
MirrorID string `json:"mirror_id"`
Forge string `json:"forge"`
Legacy bool `json:"legacy,omitempty"`
Branches string `json:"branches,omitempty"`
Tags string `json:"tags,omitempty"`
Releases string `json:"releases,omitempty"`
}
MirrorSync is one row of the replication topology: a mirror and the per-facet scope it replicates from the primary.
type ModuleConfig ¶
ModuleConfig holds per-module overrides. Options are authored INLINE (module-specific keys sit directly under the module); the retired `options:` wrapper is gone. Enabled and Exclude are the two typed fields every module shares; any other key is a module-specific option collected into Options (the heterogeneous bag the lint engine reads wholesale).
func (ModuleConfig) MarshalYAML ¶ added in v0.8.0
func (m ModuleConfig) MarshalYAML() (any, error)
MarshalYAML re-flattens: enabled/exclude plus the option keys at the module's top level, so `config render` shows the inline shape rather than the internal struct.
func (*ModuleConfig) UnmarshalYAML ¶ added in v0.8.0
func (m *ModuleConfig) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML flattens the module surface: `enabled`/`exclude` become the typed fields, every other key is a module option → Options. A stray `options:` key is the retired wrapper and is rejected loudly (rather than silently nesting under Options["options"]).
type NarrateConfig ¶ added in v0.7.0
type NarrateConfig struct {
Announces []string `yaml:"announces,omitempty"`
}
NarrateConfig is the narrate: block — the run's stdout storytelling surface. announces: lists stencil ids to render as structured-output cards at the end of the run (stdout is a target, not an endpoint). Omitted → the shipped default, [summary]. Any declared stencil id is announceable; the id "summary" resolves to the run's built-in modality story unless a user stencil shadows it (shadowing a shipped id is the override mechanism).
func (NarrateConfig) IsZero ¶ added in v0.7.0
func (n NarrateConfig) IsZero() bool
IsZero reports whether the narrate block carries no configuration.
type NetworkPrunePolicy ¶ added in v0.5.0
type NetworkPrunePolicy struct {
Unused bool `yaml:"unused,omitempty"`
}
NetworkPrunePolicy defines network pruning rules.
type NoLineageConfig ¶ added in v0.6.0
type NoLineageConfig struct {
// Mode controls the response to missing lineage.
// "error" (default): fail fast with explanation and suggested fix
// "explicit": use the provided version template
Mode string `yaml:"mode,omitempty"`
// Version is the template used when mode is "explicit".
// Must contain {sha} or {time} — hardcoded versions are rejected.
// e.g., "0.1.0-bootstrap+{sha}"
Version string `yaml:"version,omitempty"`
}
NoLineageConfig defines behavior when no tag source yields a match along the branch rule's base_from search path.
type Notification ¶ added in v0.8.0
type Notification struct {
ID string `yaml:"-"` // the map key
Provider string `yaml:"provider"` // ntfy | webhook
// Transport. Credentials follows the shipped env-prefix convention
// (credentials: NTFY → NTFY_TOKEN, sent as Authorization: Bearer).
URL string `yaml:"url,omitempty"`
Credentials string `yaml:"credentials,omitempty"`
// Message — freeform stencil bodies.
Subject string `yaml:"subject,omitempty"`
Body string `yaml:"body,omitempty"`
// When gates dispatch: outcomes: (success | failure | warning) composing with
// branches:/events:/git_tags: ("failures, but only on main"). Omitted = always.
When WhenConditions `yaml:"when,omitempty"`
// MaxLength hard-caps the rendered body in bytes (ntfy's default server limit
// is 4096). Trimming happens at a line boundary and always preserves the
// pipeline-link line so tap-through survives. 0 = no cap.
MaxLength int `yaml:"max_length,omitempty"`
// ntfy knobs — the full header vocabulary.
Priority string `yaml:"priority,omitempty"` // min|low|default|high|max
Tags StringOrList `yaml:"tags,omitempty"` // emoji tags (comma-joined into the Tags header)
Click string `yaml:"click,omitempty"` // tap-through URL (stencil body; default {pipeline_url})
Attach string `yaml:"attach,omitempty"` // attachment URL
Actions string `yaml:"actions,omitempty"` // ntfy actions spec string
Markdown bool `yaml:"markdown,omitempty"` // render body as markdown
Email string `yaml:"email,omitempty"` // forward to email address
}
Notification is one entry in the top-level notifications: block — endpoint and message FUSED in each entry (deliberately no notifier library: the library pattern pays when actions fan many-to-few, and a notification is one-to-one — message and destination are the same thought; shared topic URLs are what vars: is for). subject/body/click are freeform stencil bodies (facts + {stencil} embeds); omitted, they default to the shipped subject and the run's arc body. Gating uses the ONE when: grammar (events/branches/git_tags) extended with the outcomes: dimension; omitted when: = always.
type OIDCConfig ¶ added in v0.5.0
type OIDCConfig struct {
Audience string `yaml:"audience"`
}
OIDCConfig defines OIDC authentication for cluster access. Token is resolved from environment variable STAGEFREIGHT_OIDC at runtime.
type OIDCTrust ¶ added in v0.7.0
type OIDCTrust struct {
Issuer string `yaml:"issuer,omitempty"`
Identity string `yaml:"identity,omitempty"`
}
OIDCTrust is the expected keyless signer identity (both optional).
type OrderedAnsiblePlaybooks ¶ added in v0.9.0
type OrderedAnsiblePlaybooks []AnsiblePlaybook
OrderedAnsiblePlaybooks is the playbooks: block — an id→playbook map (key becomes AnsiblePlaybook.ID), document order preserved.
func (*OrderedAnsiblePlaybooks) UnmarshalYAML ¶ added in v0.9.0
func (o *OrderedAnsiblePlaybooks) UnmarshalYAML(n *yaml.Node) error
type OrderedBranchBuilds ¶ added in v0.8.0
type OrderedBranchBuilds []BranchBuildConfig
OrderedBranchBuilds is git.versioning.branch_builds — an id→rule map (key becomes BranchBuildConfig.ID).
func (*OrderedBranchBuilds) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedBranchBuilds) UnmarshalYAML(n *yaml.Node) error
type OrderedBuilds ¶ added in v0.8.0
type OrderedBuilds []BuildConfig
OrderedBuilds is the builds: block — an id→build map (key becomes BuildConfig.ID).
func (*OrderedBuilds) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedBuilds) UnmarshalYAML(n *yaml.Node) error
type OrderedClusters ¶ added in v0.10.0
type OrderedClusters []GitOpsCluster
OrderedClusters is the gitops: block — a clusterName→cluster map (the map key becomes GitOpsCluster.Name). Mirrors the repos:/forges:/registries: keyed maps so the cluster is named by its key, not a nested name: field.
func (OrderedClusters) ByName ¶ added in v0.10.0
func (o OrderedClusters) ByName(name string) (GitOpsCluster, bool)
ByName returns the declared cluster with the given name.
func (OrderedClusters) Primary ¶ added in v0.10.0
func (o OrderedClusters) Primary() (GitOpsCluster, bool)
Primary returns the first declared cluster. The reconcile/scribe flows are single-cluster; the keyed map is for schema consistency + naming, not fan-out.
func (*OrderedClusters) UnmarshalYAML ¶ added in v0.10.0
func (o *OrderedClusters) UnmarshalYAML(n *yaml.Node) error
type OrderedFiles ¶ added in v0.8.0
type OrderedFiles []FileDef
OrderedFiles is the files: map — id → FileDef in document order.
func (*OrderedFiles) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedFiles) UnmarshalYAML(n *yaml.Node) error
type OrderedForges ¶ added in v0.8.0
type OrderedForges []ForgeConfig
OrderedForges is the forges: block — an id→forge map (key becomes ForgeConfig.ID).
func (*OrderedForges) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedForges) UnmarshalYAML(n *yaml.Node) error
type OrderedGovProfiles ¶ added in v0.10.0
type OrderedGovProfiles []GovernanceProfile
OrderedGovProfiles is the governance.profiles: block — an id→profile map (key becomes GovernanceProfile.ID). Config-side this is used only for the presence gate (len>0); the governance package re-parses the same block richly for distribution.
func (*OrderedGovProfiles) UnmarshalYAML ¶ added in v0.10.0
func (o *OrderedGovProfiles) UnmarshalYAML(n *yaml.Node) error
type OrderedLLMs ¶ added in v0.8.0
type OrderedLLMs []LLMConfig
OrderedLLMs is the llms: map — id → LLMConfig in document order.
func (OrderedLLMs) ByID ¶ added in v0.8.0
func (o OrderedLLMs) ByID() map[string]LLMConfig
ByID returns a lookup map of the llms library keyed by id.
func (*OrderedLLMs) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedLLMs) UnmarshalYAML(n *yaml.Node) error
type OrderedNotifications ¶ added in v0.8.0
type OrderedNotifications []Notification
OrderedNotifications is the notifications: map — id → Notification in document order.
func (OrderedNotifications) IsZero ¶ added in v0.8.0
func (o OrderedNotifications) IsZero() bool
IsZero reports whether no notifications are declared (the dispatch gate).
func (*OrderedNotifications) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedNotifications) UnmarshalYAML(n *yaml.Node) error
type OrderedOrgs ¶ added in v0.10.0
type OrderedOrgs []OrgConfig
OrderedOrgs is the orgs: block — an id→org map (the map key becomes OrgConfig.ID). An org is identity ONLY: a maintainer and an open aliases map (the name-forms used to build coordinates on different surfaces). It carries no forge and no credentials — each surface owns its own credential, and a governance write token is DERIVED, not declared here. That identity≠credentials split is a hard invariant; see docs/design/identity-model.md.
func (OrderedOrgs) ByID ¶ added in v0.10.0
func (o OrderedOrgs) ByID(id string) (OrgConfig, bool)
ByID returns the declared org with the given id.
func (*OrderedOrgs) UnmarshalYAML ¶ added in v0.10.0
func (o *OrderedOrgs) UnmarshalYAML(n *yaml.Node) error
type OrderedRegistries ¶ added in v0.8.0
type OrderedRegistries []RegistryConfig
OrderedRegistries is the registries: block — an id→registry map (key becomes RegistryConfig.ID).
func (*OrderedRegistries) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedRegistries) UnmarshalYAML(n *yaml.Node) error
type OrderedRepos ¶ added in v0.8.0
type OrderedRepos []RepoConfig
OrderedRepos is the repos: block — an id→repo map (key becomes RepoConfig.ID).
func (*OrderedRepos) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedRepos) UnmarshalYAML(n *yaml.Node) error
type OrderedSigningProfiles ¶ added in v0.8.0
type OrderedSigningProfiles []SigningProfile
OrderedSigningProfiles is signing.profiles — an id→profile map (key becomes SigningProfile.ID).
func (*OrderedSigningProfiles) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedSigningProfiles) UnmarshalYAML(n *yaml.Node) error
type OrderedStencils ¶ added in v0.8.0
type OrderedStencils []StencilDef
OrderedStencils is the top-level stencils: library — id → StencilDef, document order.
func (OrderedStencils) ByID ¶ added in v0.8.0
func (o OrderedStencils) ByID() map[string]StencilDef
ByID returns a lookup map of the stencil library keyed by id.
func (*OrderedStencils) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedStencils) UnmarshalYAML(n *yaml.Node) error
type OrderedTagSources ¶ added in v0.8.0
type OrderedTagSources []TagSourceConfig
OrderedTagSources is git.tags — an id→{pattern} map (key becomes TagSourceConfig.ID).
func (*OrderedTagSources) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedTagSources) UnmarshalYAML(n *yaml.Node) error
type OrderedTargets ¶ added in v0.8.0
type OrderedTargets []TargetConfig
OrderedTargets is the publish: block — the distribution targets as an id→target map (the map key becomes each target's ID). Backed by a slice so execution order (YAML map order) is preserved. This is the ONLY accepted shape.
func (*OrderedTargets) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedTargets) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML decodes the id→target map in document order, stamping each target's ID from its key (strict-decoded — see decodeIDMap).
type OrderedTestSuites ¶ added in v0.8.0
type OrderedTestSuites []TestSuite
OrderedTestSuites is the test.suites: block — an id→suite map (key becomes TestSuite.ID). The ONLY accepted shape; the retired list form is rejected at decode ("must be an id → entry map").
func (*OrderedTestSuites) UnmarshalYAML ¶ added in v0.8.0
func (o *OrderedTestSuites) UnmarshalYAML(n *yaml.Node) error
type OrgConfig ¶ added in v0.10.0
type OrgConfig struct {
ID string `yaml:"-"` // from the map key
// Maintainer is the "Name <email>" contact for this org's repos.
Maintainer string `yaml:"maintainer,omitempty"`
// Aliases is an OPEN map of name-forms used to build coordinates on different
// surfaces — e.g. {handle: hlhd, lower: homelabhd, gitlab_group: "PrPlanIT/HomeLabHD"}.
// A surface's default_path references one as {org.<alias>}. Common case is a single
// entry; string→string only (a coordinate segment is always a scalar).
Aliases map[string]string `yaml:"aliases,omitempty"`
}
OrgConfig is one organization/owner identity, keyed by its id in the orgs: map. Identity only — no forge, no credentials.
type OutdatedGate ¶ added in v0.10.0
type OutdatedGate struct {
// At is the smallest magnitude that trips the gate: "major" | "minor" | "patch",
// or "off". Empty defaults to "off" — no gate, so this is zero-change until a
// project opts in.
At string `yaml:"at,omitempty"`
// Action is what a tripped gate does: "warn" (default) or "error". Warn is the
// default deliberately: an available update is information, and a policy that
// breaks a build the day upstream publishes is one operators disable entirely.
Action string `yaml:"action,omitempty"`
}
OutdatedGate declares the update magnitude that trips the gate, and what tripping it does. Split in two because the threshold and the response are independent decisions: a fleet can surface every held major without any repo failing on it, then tighten to error per repo once the noise is understood.
func (OutdatedGate) EffectiveAction ¶ added in v0.10.0
func (g OutdatedGate) EffectiveAction() string
EffectiveAction resolves the response, defaulting to "warn" — reporting, never failing, unless the operator asks for a hard gate.
func (OutdatedGate) EffectiveAt ¶ added in v0.10.0
func (g OutdatedGate) EffectiveAt() string
EffectiveAt resolves the magnitude threshold, defaulting to "off".
type OutputSpec ¶ added in v0.7.0
type OutputSpec struct {
Type string `yaml:"type"`
Source string `yaml:"source"`
Worktree *WorktreeSpec `yaml:"worktree,omitempty"`
}
OutputSpec declares one captured build output: what the command produced (Source, repo-relative) and its artifact class (Type ∈ tree | file | binary). Worktree opts the output into the git working tree during Narrate (so it can be committed or read by patches); absent, the output is a pure artifact (transported/published, never landed).
func (OutputSpec) LandsInWorktree ¶ added in v0.7.0
func (o OutputSpec) LandsInWorktree() bool
LandsInWorktree reports whether this output is materialized into the working tree.
func (OutputSpec) WorktreePath ¶ added in v0.7.0
func (o OutputSpec) WorktreePath() string
WorktreePath is where the output lands in the repo: its explicit worktree path, or its Source path when worktree is just `true`.
type PKCS11Trust ¶ added in v0.7.0
type PKCS11Trust struct {
Ref string `yaml:"ref"`
}
PKCS11Trust selects the PKCS#11 transport for a `hardware` profile via a LOGICAL ref (e.g. "release"), bound to a concrete `pkcs11:` URI (module path + slot/object) only at render time via SF_PKCS11_<REF>. So a profile names "my signing token", never a machine-specific module path. Absent → the hardware class falls back to FIDO2 (cosign --sk). The renderer treats transport as an implementation detail; the class still means only "a non-exportable key in a signing device".
type PagesVersioning ¶ added in v0.7.0
type PagesVersioning struct {
// Mode: "replace" (each release overwrites; the only mode implemented in P1) or
// "keep" (every released version stays browsable — reserved for phase 2, rejected
// in P1 rather than silently ignored).
Mode string `yaml:"mode,omitempty"`
}
PagesVersioning controls how released versions of a static site are published.
type PhraseRewrite ¶ added in v0.5.0
PhraseRewrite replaces exact substrings.
type PresetLoader ¶ added in v0.6.0
PresetLoader fetches preset content by path. Implementations: local filesystem, git repo checkout.
type PresetSource ¶ added in v0.8.0
type PresetSource struct {
Provider string `yaml:"provider,omitempty"`
RepoURL string `yaml:"repo_url,omitempty"`
ProjectID string `yaml:"project_id,omitempty"`
Ref string `yaml:"ref,omitempty"`
CachePolicy string `yaml:"cache_policy,omitempty"`
}
PresetSource is governance-distribution metadata recording where a satellite's presets were frozen from — see the Config.PresetSource field. Present so a governed config decodes under KnownFields(true); ignored at runtime today.
type ProducerCoords ¶ added in v0.8.0
type ProducerCoords struct {
Provider string // github, gitlab, gitea, forgejo
Host string // github.com, gitlab.prplanit.com, ...
Project string // owner/name
Module string // host/owner/name (Go module path)
}
ProducerCoords are the repository coordinates a named-producer badge derives from the publish-origin repo (or an explicit repos: id override), so props like goreportcard / github-* stop restating {var:...} coordinates that already live in repos:.
func ResolveProducerCoords ¶ added in v0.8.0
func ResolveProducerCoords(cfg *Config, repoOverride string) (*ProducerCoords, error)
ResolveProducerCoords resolves the coordinates for a named producer. When repoOverride names a repos: entry, that repo's coordinates are used; otherwise the publish-origin repo (role publish-origin, falling back to primary). This is what lets a named producer be self-contained — no module:/repo: param restating coordinates already declared once in repos:.
type ProtectionPolicy ¶ added in v0.5.0
type ProtectionPolicy struct {
Images ImageProtection `yaml:"images,omitempty"`
Volumes VolumeProtection `yaml:"volumes,omitempty"`
}
ProtectionPolicy defines what host objects are never pruned.
type ProvenanceConfig ¶ added in v0.7.0
type ProvenanceConfig struct {
Generated []string `yaml:"generated,omitempty"`
Vendored []string `yaml:"vendored,omitempty"`
}
ProvenanceConfig lets a project DECLARE file provenance that can't be inferred from bytes or paths (e.g. a build's CSS output). Declarations are the highest-confidence provenance signal — they outrank heuristics — because only the project knows its own build. Globs match the repo-relative path. Provenance only ever RELAXES authored-code hygiene (whitespace/line-endings/length); security and supply-chain checks ignore it.
type PrunePolicy ¶ added in v0.5.0
type PrunePolicy struct {
Images ImagePrunePolicy `yaml:"images,omitempty"`
BuildCache BuildCachePrunePolicy `yaml:"build_cache,omitempty"`
Containers ContainerPrunePolicy `yaml:"containers,omitempty"`
Networks NetworkPrunePolicy `yaml:"networks,omitempty"`
}
PrunePolicy defines which host objects are eligible for removal.
type RegexRewrite ¶ added in v0.5.0
RegexRewrite replaces regex matches.
type RegistryConfig ¶ added in v0.6.0
type RegistryConfig struct {
ID string `yaml:"id"` // unique identifier (e.g., "dockerhub")
Provider string `yaml:"provider"` // docker, harbor, ghcr, quay, gitea, generic
URL string `yaml:"url"` // registry URL (e.g., "docker.io")
Credentials string `yaml:"credentials,omitempty"` // env var prefix for token resolution
DefaultPath string `yaml:"default_path,omitempty"` // default image path (e.g., "{var:org}/{var:repo}")
}
RegistryConfig declares an OCI registry host. Declared once, referenced by targets.
func FindRegistryByID ¶ added in v0.6.0
func FindRegistryByID(registries []RegistryConfig, id string) *RegistryConfig
FindRegistryByID returns the registry with the given id, or nil.
type ReleaseConfig ¶
type ReleaseConfig struct {
Preset string `yaml:"preset,omitempty"`
Enabled bool `yaml:"enabled"`
Required *bool `yaml:"required,omitempty"` // failure is hard pipeline fail (default: false)
// SecuritySummary attaches the security summary to the release. The summary's
// location is security.output — this is a yes/no toggle, not a path.
SecuritySummary bool `yaml:"security_summary"`
RegistryLinks bool `yaml:"registry_links"`
CatalogLinks bool `yaml:"catalog_links"`
// Render controls release rendering (default DefaultReleasePresentation; a
// partial render: block overlays those defaults).
Render ReleasePresentation `yaml:"render,omitempty"`
RunFrom RunFromConfig `yaml:"run_from,omitempty"` // gate mutation to declared origin
}
ReleaseConfig holds configuration for the release subsystem.
func DefaultReleaseConfig ¶
func DefaultReleaseConfig() ReleaseConfig
DefaultReleaseConfig returns sensible defaults for release management.
func (ReleaseConfig) IsRequired ¶ added in v0.5.0
func (r ReleaseConfig) IsRequired() bool
IsRequired returns whether release failure is a hard pipeline fail. Default: false.
type ReleasePresentation ¶ added in v0.5.0
type ReleasePresentation struct {
MaxEntries int `yaml:"max_entries"`
GroupByType bool `yaml:"group_by_type"`
Style string `yaml:"style"` // concise | explanatory | technical
IncludeReleaseVisibleOnly bool `yaml:"include_release_visible_only"`
}
ReleasePresentation controls release notes rendering (release.render).
func DefaultReleasePresentation ¶ added in v0.8.0
func DefaultReleasePresentation() ReleasePresentation
DefaultReleasePresentation is the default release.render policy.
type RemediationConfig ¶ added in v0.7.0
type RemediationConfig struct {
TrailingWhitespace *bool `yaml:"trailing_whitespace,omitempty"` // default ON under --fix-safe
FinalNewline *bool `yaml:"final_newline,omitempty"` // default ON under --fix-safe
}
RemediationConfig is the granular opt-in for `--fix-safe`. Each field is a *bool: nil means "use the safe default" (on for the conservative hygiene fixes), so the one-shot `--fix-safe` flow works out of the box while a project can still disable a category. Categories that are policy-dependent (line endings, tab/space) default OFF and must be turned on explicitly. Only authored files are ever mutated — generated/vendored/lock emit no hygiene findings, so they carry no fixes.
type RenderConfig ¶ added in v0.5.0
type RenderConfig struct {
EmptyStrategy string `yaml:"empty_strategy"` // prompt | fail | allow_empty
}
RenderConfig controls glossary-level output defaults. Surface-specific max entries live in presentation config.
type RepoConfig ¶ added in v0.6.0
type RepoConfig struct {
ID string `yaml:"id"` // unique identifier
Forge string `yaml:"forge"` // references forges[].id
Project string `yaml:"project"` // project path on the forge (e.g., "{var:gitlab_group}/{var:repo}")
Roles []string `yaml:"roles,omitempty"` // ["primary"] | ["mirror"] | ["mirror", "publish-origin"] | []
Branches BranchesConfig `yaml:"branches,omitempty"` // branch identity (default, protected, etc.)
Worktree string `yaml:"worktree,omitempty"` // local working tree path (primary only)
Ref string `yaml:"ref,omitempty"` // pinned ref for non-primary repos (governance, presets)
Sync SyncConfig `yaml:"sync,omitempty"` // mirror sync domains
}
RepoConfig declares a project on a forge. References forge by id. Roles are explicit and composable:
- "primary": exactly 1 required — authoritative source
- "mirror": 0 to many — derivative copies
- "publish-origin": 0 or 1 — where rendered artifacts are served from
- empty: addressable, no special behavior
Forbidden combinations: primary + mirror (authoritative ≠ derivative). Allowed combinations: publish-origin + primary, publish-origin + mirror.
func FindRepoByID ¶ added in v0.6.0
func FindRepoByID(repos []RepoConfig, id string) *RepoConfig
FindRepoByID returns the repo with the given id, or nil.
func FindRepoWithRole ¶ added in v0.6.0
func FindRepoWithRole(repos []RepoConfig, role string) *RepoConfig
FindRepoWithRole returns the first repo that has the given role, or nil.
func MirrorRepos ¶ added in v0.6.0
func MirrorRepos(repos []RepoConfig) []RepoConfig
MirrorRepos returns all repos with the mirror role.
func (RepoConfig) HasRole ¶ added in v0.6.0
func (r RepoConfig) HasRole(role string) bool
HasRole returns true if the repo has the given role.
type ResolvedRegistry ¶ added in v0.6.0
type ResolvedRegistry struct {
ID string
Provider string // from registry
URL string // from registry
Path string // from registry default_path or target override
Credentials string // from registry
}
ResolvedRegistry is a fully resolved registry target with all identity fields populated from the registry graph. Ready for buildx/push.
func ResolveRegistryByID ¶ added in v0.10.0
func ResolveRegistryByID(id string, registries []RegistryConfig, vars map[string]string) *ResolvedRegistry
ResolveRegistryByID resolves a registry from the graph by its config id alone, with {var:} templates expanded in URL and default_path. It is the addressing primitive for {registry.<id>...} template tokens: a registry is referenced only by the id it was given in registries:, never by a provider-literal shorthand (which cannot distinguish two registries of the same provider and picks one by luck). Returns nil for an unknown id.
func ResolveRegistryForTarget ¶ added in v0.6.0
func ResolveRegistryForTarget(target TargetConfig, registries []RegistryConfig, vars map[string]string) (*ResolvedRegistry, error)
ResolveRegistryForTarget resolves a target's registry identity from the registry graph. Path comes from target override or registry default_path.
type ResolvedRepo ¶ added in v0.6.0
type ResolvedRepo struct {
ID string
Provider string // from forge
BaseURL string // from forge
Project string // from repo
Credentials string // from forge
Roles []string // from repo (primary, mirror, publish-origin)
DefaultBranch string // flattened from repo.Branches.Default
Worktree string
Ref string
Sync SyncConfig
}
ResolvedRepo is a fully resolved repo with all identity fields populated from the forge + repo graph. Ready for forge client creation.
DefaultBranch is the flattened view of repo.Branches.Default — resolved once at load time so consumers don't need to know the nested shape.
func ResolveAllMirrors ¶ added in v0.6.0
func ResolveAllMirrors(repos []RepoConfig, forges []ForgeConfig, vars map[string]string) ([]*ResolvedRepo, error)
ResolveAllMirrors resolves all mirror repos against the forge graph.
func ResolvePrimary ¶ added in v0.6.0
func ResolvePrimary(repos []RepoConfig, forges []ForgeConfig, vars map[string]string) (*ResolvedRepo, error)
ResolvePrimary resolves the primary repo against the forge graph.
func ResolveRepo ¶ added in v0.6.0
func ResolveRepo(repo RepoConfig, forges []ForgeConfig, vars map[string]string) (*ResolvedRepo, error)
ResolveRepo resolves a repo entry against the forge graph. Returns error if the referenced forge doesn't exist.
func (ResolvedRepo) HasRole ¶ added in v0.6.0
func (r ResolvedRepo) HasRole(role string) bool
HasRole returns true if the resolved repo has the given role.
type ResolvedSigningProfile ¶ added in v0.7.0
type ResolvedSigningProfile struct {
ID string
Class string
KeyRef string
KMSRef string
PKCS11Ref string
OIDCIssuer string
OIDCIdentity string
PhysicalPresence bool
NonExportable bool
TransparencyLog *bool // nil = use the class default
Attestation bool
Enforce bool // signing failure is fatal (orchestration policy, not trust)
AllowFallback bool // an unresolved explicit signer may fall back to Tier-0
}
ResolvedSigningProfile is the flattened, validated view consumed by the pure compiler (src/sign). Exactly one trust class; assurance keywords collapsed to booleans; logical refs carried verbatim (bound to keys/URIs only at render).
func ResolveSigningProfileByID ¶ added in v0.7.0
func ResolveSigningProfileByID(profiles []SigningProfile, id string) (*ResolvedSigningProfile, error)
ResolveSigningProfileByID resolves a profile by id for explicit signing flows (e.g. `stagefreight sign --profile <id>`). Unknown id → error; the reserved `legacy` id resolves to the synthesized default.
func ResolveSigningProfileForTarget ¶ added in v0.7.0
func ResolveSigningProfileForTarget(t TargetConfig, profiles []SigningProfile) (*ResolvedSigningProfile, error)
ResolveSigningProfileForTarget returns the resolved profile a target signs under. No signing_profile → the synthesized `legacy` profile (single path, never nil for a signable target). A set-but-unknown reference is an error. Mirrors ResolveRegistryForTarget.
func (*ResolvedSigningProfile) IsLegacyDefault ¶ added in v0.7.0
func (r *ResolvedSigningProfile) IsLegacyDefault() bool
IsLegacyDefault reports whether this is the synthesized implicit default profile (no explicit signing_profile on the target) — the always-on path that may fall to Tier-0 or silently skip, as opposed to an explicit profile that must resolve.
type RetentionPolicy ¶
type RetentionPolicy struct {
KeepLast int `yaml:"keep_last"` // keep the N most recent tags per series (0/-1/unset = ∞)
KeepDaily int `yaml:"keep_daily"` // keep one per day for the last N days
KeepWeekly int `yaml:"keep_weekly"` // keep one per week for the last N weeks
KeepMonthly int `yaml:"keep_monthly"` // keep one per month for the last N months
KeepYearly int `yaml:"keep_yearly"` // keep one per year for the last N years
KeepBranches int `yaml:"keep_branches"` // keep the N most-recent identity groups per template (bounds retired branches; 0/unset = ∞)
MaxAge string `yaml:"max_age"` // keep items newer than this ("14d", "72h"); additive like keep_* — alone it means "only the recent survive"
Identity []string `yaml:"identity"` // extra identity vars beyond the {branch}/{env} defaults — partition tags into independent series
Protect []string `yaml:"protect"` // tag patterns that are never deleted, an explicit override
Refs []RetentionRef `yaml:"refs"` // scoped overrides: a different policy for items matching a pattern (first match wins; unset fields inherit this default)
}
RetentionPolicy defines how many tags/releases to keep using time-bucketed rules. Policies are additive — a tag survives if ANY rule wants to keep it. This mirrors restic's forget policy.
func (RetentionPolicy) Active ¶
func (r RetentionPolicy) Active() bool
Active returns true if any retention rule is configured. keep_last/buckets are active only when positive (0/-1/unset all mean ∞ / keep-all); keep_branches is a group-count bound that is likewise only active when positive. max_age and any scoped ref rule likewise activate the policy.
func (*RetentionPolicy) UnmarshalYAML ¶
func (r *RetentionPolicy) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML implements custom unmarshaling so retention accepts both:
retention: 10 → RetentionPolicy{KeepLast: 10}
retention:
keep_last: 3
keep_daily: 7 → RetentionPolicy{KeepLast: 3, KeepDaily: 7}
type RetentionRef ¶ added in v0.10.0
type RetentionRef struct {
Match string `yaml:"match"` // pattern (same syntax as protect/templates)
KeepLast int `yaml:"keep_last"`
KeepDaily int `yaml:"keep_daily"`
KeepWeekly int `yaml:"keep_weekly"`
KeepMonthly int `yaml:"keep_monthly"`
KeepYearly int `yaml:"keep_yearly"`
MaxAge string `yaml:"max_age"`
}
RetentionRef is one scoped retention override: items matching Match are governed by this rule set instead of the default policy. Fields left unset inherit the default's value — a ref narrows or widens specific rules without restating the whole policy. The SAME grammar applies at every retention site (publish targets, toolchains, declared image eviction, releases, packages, mirrors) — one engine implements it.
type RewriteConfig ¶ added in v0.5.0
type RewriteConfig struct {
Phrases []PhraseRewrite `yaml:"phrases,omitempty"`
Regex []RegexRewrite `yaml:"regex,omitempty"`
}
RewriteConfig defines deterministic text transformations.
type RoutingConfig ¶ added in v0.6.0
type RoutingConfig struct {
Default RoutingSpec `yaml:"default,omitempty"`
Audition RoutingSpec `yaml:"audition,omitempty"`
Perform RoutingSpec `yaml:"perform,omitempty"`
Review RoutingSpec `yaml:"review,omitempty"`
Publish RoutingSpec `yaml:"publish,omitempty"`
Narrate RoutingSpec `yaml:"narrate,omitempty"`
}
RoutingConfig declares runner placement per phase. Default applies to EVERY job; a per-phase field overrides it for that job. Empty ⇒ no constraint (any runner). This matters beyond consistency: GitLab's local runner cache is per-runner, so the build/toolchain caches StageFreight configures only actually persist across the pipeline when its phases land on the SAME runner — otherwise floating jobs re-provision toolchains every run. Set `default` to keep the whole pipeline on one runner.
func (RoutingConfig) For ¶ added in v0.7.0
func (r RoutingConfig) For(phase string) []string
For returns the runner labels for a phase: the per-phase override if set, else the Default. nil when neither is configured (the job is unconstrained).
type RoutingSpec ¶ added in v0.6.0
type RoutingSpec struct {
Labels []string `yaml:"labels,omitempty"`
}
RoutingSpec declares runner placement labels for a single phase.
type RunFromConfig ¶ added in v0.6.0
type RunFromConfig struct {
Allow []string `yaml:"allow,omitempty"` // permitted origins: "primary"
Mismatch string `yaml:"mismatch,omitempty"` // "read-only" (default), "exit", "ignore"
}
RunFromConfig gates mutation to declared execution origins. Attached to mutating surfaces (release, docs.commit, dependency.commit, targets).
func (RunFromConfig) IsActive ¶ added in v0.6.0
func (rf RunFromConfig) IsActive() bool
IsActive returns true if run_from has any allow rules configured.
type RunFromResult ¶ added in v0.6.0
type RunFromResult struct {
Matched bool // true if current context matches an allowed origin
Mode string // "read-only", "exit", "ignore", or "" (no restriction)
Reason string // human-readable explanation (empty when matched or unconfigured)
}
RunFromResult is the evaluated outcome of a run_from guard.
func EvaluateRunFrom ¶ added in v0.6.0
func EvaluateRunFrom(rf RunFromConfig, ciRepoURL, primaryURL string) RunFromResult
EvaluateRunFrom checks whether the current execution context is authorized to perform a mutation guarded by a run_from config.
ciRepoURL is the CI execution context (SF_CI_REPO_URL). primaryURL is sources.primary.url from config.
type ScannerCacheConfig ¶ added in v0.5.0
type ScannerCacheConfig struct {
MaxSize string `yaml:"max_size,omitempty"` // e.g. "500MB" — full-clear when exceeded
MaxAge string `yaml:"max_age,omitempty"` // e.g. "7d" — full-clear when oldest file exceeds age
}
ScannerCacheConfig is the cache policy for a single scanner. Any field set = persistent cache enabled for this tool. All fields empty = no StageFreight-managed persistence (tool defaults). Eviction is full-clear (opaque DBs, no granular eviction).
type ScannersConfig ¶
type ScannersConfig struct {
Trivy *bool `yaml:"trivy,omitempty"` // run Trivy image scan (default: true)
Grype *bool `yaml:"grype,omitempty"` // run Grype image scan (default: true)
}
ScannersConfig controls which vulnerability scanners are enabled. Both default to true — scanners still require their binary in PATH. Uses *bool so omitting a key preserves the default instead of zeroing it.
func (ScannersConfig) GrypeEnabled ¶
func (s ScannersConfig) GrypeEnabled() bool
GrypeEnabled returns whether Grype scanning is enabled (default: true).
func (ScannersConfig) TrivyEnabled ¶
func (s ScannersConfig) TrivyEnabled() bool
TrivyEnabled returns whether Trivy scanning is enabled (default: true).
type Scoped ¶ added in v0.10.0
Scoped[T] is a value that is either an inferred DEFAULT (the common case) or scoped per surface — the same override idiom as `names`, for content values (description, readme). A plain value is the default used on every un-named surface; a map form
{ default: <T>, <surface>: <T>, … }
overrides specific surfaces. Resolution at surface S is BySurface[S] if present, else Default.
Disambiguation is by YAML shape: T here is always a scalar-or-list (StringOrList or string) — never itself a map — so a MappingNode can only mean the scoped form; anything else is the plain default. Note: only the DEFAULT of a Scoped[StringOrList] may be a tiered list; a named surface takes a single value (one endpoint, one value), enforced in validation rather than the type.
type ScribeCommit ¶ added in v0.8.0
type ScribeCommit struct {
Type string `yaml:"type,omitempty"`
Message string `yaml:"message,omitempty"`
Add []string `yaml:"add,omitempty"`
Push bool `yaml:"push,omitempty"`
SkipCI bool `yaml:"skip_ci,omitempty"`
RunFrom RunFromConfig `yaml:"run_from,omitempty"`
}
ScribeCommit is scribe's auto-commit action.
func (ScribeCommit) IsZero ¶ added in v0.8.0
func (c ScribeCommit) IsZero() bool
IsZero reports whether the commit action is unset.
type ScribeConfig ¶ added in v0.8.0
type ScribeConfig struct {
Store string `yaml:"store,omitempty"` // dir for rendered file assets (default .stagefreight/scribe); path = {store}/{id}.svg
Files OrderedFiles `yaml:"files,omitempty"` // id → placement region referencing stencils
Commit ScribeCommit `yaml:"commit,omitempty"` // scribe's own auto-commit action
}
ScribeConfig is the scribe: block — place rendered stencils into repository files and commit them: files: (placement regions whose bodies reference stencils by {id}) + commit:. The reusable stencil library it draws from lives at the top-level stencils: block (Config.Stencils) — shared with narrate and release.
func (ScribeConfig) IsZero ¶ added in v0.8.0
func (s ScribeConfig) IsZero() bool
IsZero reports whether scribe declares nothing (the phase presence gate). Note it does NOT consider stencils: the library is presence-neutral (shared, may exist with no scribe placement), so only files/commit gate the scribe/narrate stage.
type SectionState ¶ added in v0.6.0
type SectionState struct {
Name string `json:"name"`
Kind string `json:"kind"` // "execution" | "capability" | "structural"
Active bool `json:"active"`
SourcePresent bool `json:"source_present"`
Provenance string `json:"provenance"` // "manifest" | "preset" | "none"
ResolutionStatus string `json:"resolution_status"` // "resolved" | "partial" | "none"
}
SectionState is the resolved state of one config domain section.
Provenance only applies when Active == true. When Active == false, Provenance MUST be "none" — inactive sections have no provenance because they do not exist in the runtime model.
type SecurityCacheConfig ¶ added in v0.5.0
type SecurityCacheConfig struct {
Trivy ScannerCacheConfig `yaml:"trivy,omitempty"`
Grype ScannerCacheConfig `yaml:"grype,omitempty"`
}
SecurityCacheConfig controls persistent vuln DB caching per scanner tool. These are opaque tool-managed directories — StageFreight hosts and bounds them, but does not manage their internal structure.
type SecurityConfig ¶
type SecurityConfig struct {
Preset string `yaml:"preset,omitempty"`
Enabled bool `yaml:"enabled"` // run vulnerability scanning (default: true)
Required *bool `yaml:"required,omitempty"` // failure is hard pipeline fail (default: false)
Scanners ScannersConfig `yaml:"scanners"` // per-scanner toggles
SBOMEnabled bool `yaml:"sbom"` // generate SBOM artifacts (default: true)
FailOnCritical bool `yaml:"fail_on_critical"` // DEPRECATED: use fail_on. Alias — true → fail_on: critical.
OutputDir string `yaml:"output"` // directory for scan artifacts (default: .stagefreight/security)
// FailOn is the severity threshold at or above which the scan fails the build:
// "critical" | "high" | "medium" | "low" | "off". Empty falls back to the
// deprecated fail_on_critical (true → "critical"), then to "off" — so the
// default stays informational (no gate), exactly as today.
FailOn string `yaml:"fail_on,omitempty"`
// UnreachableVulns is the policy for vulnerabilities a reachability analyzer
// proved are never called: "pass" (default — excused from the gate) or "fail"
// (gated on severity regardless of reachability). Only vulns with a
// proven-unreachable verdict are affected; everything else is "unknown" and
// gates normally.
UnreachableVulns string `yaml:"unreachable_vulns,omitempty"`
// Exceptions are reviewed, on-record decisions to excuse specific advisories from the
// fail_on gate — the human counterpart to the reachability excusal above. An excepted
// finding STILL appears in the scan report (it is not hidden); the exception only stops
// it from FAILING the build. Each carries a mandatory reason and an optional expiry: an
// expired exception lapses (the advisory gates again and the lapse is surfaced), and one
// with no expiry is a standing decision (reported as such). This does nothing unless
// fail_on is set — with the gate off, everything is already informational.
Exceptions []SecurityException `yaml:"exceptions,omitempty"`
// ReleaseDetail is the default detail level for security info in release notes.
// Values: "none", "counts", "detailed", "full" (default: "counts").
ReleaseDetail string `yaml:"release_detail"`
// ReleaseDetailRules are conditional overrides evaluated top-down (first match wins).
// Uses the standard Condition primitive for tag/branch matching with ! negation.
ReleaseDetailRules []DetailRule `yaml:"release_detail_rules"`
// Cache controls persistent vulnerability DB caching per scanner.
// Each tool's max_size triggers full-clear when exceeded (opaque DBs, no granular eviction).
// Empty/omitted per tool = no StageFreight-managed persistence for that tool.
Cache SecurityCacheConfig `yaml:"cache,omitempty"`
// OverwhelmMessage is the message lines shown when >1000 vulns are found.
// Defaults to ["…maybe start here:"] with the OverwhelmLink below.
OverwhelmMessage []string `yaml:"overwhelm_message"`
// OverwhelmLink is an optional URL appended after OverwhelmMessage.
// Defaults to a Psychology Today anxiety page. Empty string disables.
OverwhelmLink string `yaml:"overwhelm_link"`
}
SecurityConfig holds security scanning configuration.
func DefaultSecurityConfig ¶
func DefaultSecurityConfig() SecurityConfig
DefaultSecurityConfig returns sensible defaults for security scanning.
func (SecurityConfig) EffectiveFailOn ¶ added in v0.7.0
func (s SecurityConfig) EffectiveFailOn() string
EffectiveFailOn resolves the severity threshold at or above which the security scan fails the build. Precedence: explicit fail_on > the deprecated fail_on_critical bool (true → "critical") > "off" — so with neither set the scan stays informational, exactly as it does today. Returns a lowercased "critical" | "high" | "medium" | "low" | "off".
func (SecurityConfig) IsRequired ¶ added in v0.5.0
func (s SecurityConfig) IsRequired() bool
IsRequired returns whether security failure is a hard pipeline fail. Default: false.
func (SecurityConfig) UnreachablePolicy ¶ added in v0.7.0
func (s SecurityConfig) UnreachablePolicy() string
UnreachablePolicy resolves how proven-unreachable vulnerabilities are gated: "pass" (default — excused) or "fail".
type SecurityException ¶ added in v0.9.1
type SecurityException struct {
// ID is the advisory this excepts (CVE / GHSA), matched case-insensitively. Required.
ID string `yaml:"id"`
// Reason is why the advisory is accepted or not applicable. Required — there is no
// anonymous excusal; the justification is the whole point of the record.
Reason string `yaml:"reason"`
// Expires optionally lapses the exception on a date (YYYY-MM-DD). Past its expiry the
// advisory gates again and the lapse is surfaced. Omit for a standing decision (an
// architectural fact), which is reported as a permanent exception.
Expires string `yaml:"expires,omitempty"`
// Package optionally scopes the exception to a single package name, so a later,
// unrelated advisory that reuses the same ID against a different package still gates.
Package string `yaml:"package,omitempty"`
}
SecurityException excuses one advisory from the fail_on gate on record. It never removes the finding from the report — it only marks it as a reviewed accepted-risk / not-applicable decision so it does not fail the build.
type SigningConfig ¶ added in v0.7.0
type SigningConfig struct {
Enabled *bool `yaml:"enabled,omitempty"` // nil/true = signing allowed; false = all signing off
AutoProvision bool `yaml:"auto_provision,omitempty"` // explicit consent to create/manage a Tier-0 identity
StateDir StateDir `yaml:"state_dir,omitempty"` // where persistent signing material lives
Profiles OrderedSigningProfiles `yaml:"profiles,omitempty"` // id→profile map
}
SigningConfig is the OPERATIONAL signing block (`signing:`), distinct from the trust-profile list (`signing.profiles`). It governs whether StageFreight may sign at all, whether it may create/manage Tier-0 identity material on the operator's behalf, and where that material persists.
The two toggles are deliberately separate — collapsing them would let the system silently mint a trust identity nobody consented to:
- enabled = "StageFreight may perform signing"
- auto_provision = "StageFreight may create/manage a Tier-0 identity"
`auto_provision` defaults FALSE: with no config, StageFreight mints nothing and signs only with an explicit key/profile. Opinionated "always-on" defaults belong in a runner/distribution config (visible, editable, removable), never in core.
func (SigningConfig) SigningEnabled ¶ added in v0.7.0
func (c SigningConfig) SigningEnabled() bool
SigningEnabled reports whether signing may run. Default (unset) is true — signing is a first-class capability; `enabled: false` is the global kill switch.
type SigningProfile ¶ added in v0.7.0
type SigningProfile struct {
ID string `yaml:"id"`
Requires StringOrList `yaml:"requires"` // trust class(es); v1 enforces exactly one
// Class reference blocks — at most one, matching the declared class.
Key *KeyTrust `yaml:"key,omitempty"`
OIDC *OIDCTrust `yaml:"oidc,omitempty"`
KMS *KMSTrust `yaml:"kms,omitempty"`
PKCS11 *PKCS11Trust `yaml:"pkcs11,omitempty"` // hardware transport selector (optional; absent = FIDO2 --sk)
// Assurance properties (hardware-class ONLY; enforced in validation). The
// value is the keyword "required" (absent = not required). The renderer later
// selects a transport that satisfies them — they are never device names here.
PhysicalPresence string `yaml:"physical_presence,omitempty"`
NonExportable string `yaml:"non_exportable,omitempty"`
// TransparencyLog overrides the per-class default (on for oidc, off otherwise).
TransparencyLog *bool `yaml:"transparency_log,omitempty"`
// Attestation also emits a provenance attestation alongside the signature.
Attestation bool `yaml:"attestation,omitempty"`
// Enforce makes a signing failure fatal to the phase (default: best-effort —
// warn + record a failed outcome, let the build proceed). An orchestration
// policy, NOT a trust requirement — it never enters the SignPlan; Publish reads
// it to decide block-vs-proceed (foundational invariant 4).
Enforce bool `yaml:"enforce,omitempty"`
// AllowFallback permits an explicitly-configured signer that fails to resolve to
// fall back to the auto-provisioned Tier-0 identity. Default false: an explicit
// trust expectation that is unmet fails LOUDLY, never silently downgrades.
AllowFallback bool `yaml:"allow_fallback,omitempty"`
}
SigningProfile is a named, generic trust profile.
func FindSigningProfileByID ¶ added in v0.7.0
func FindSigningProfileByID(profiles []SigningProfile, id string) *SigningProfile
FindSigningProfileByID returns the profile with the given id, or nil.
func NormalizeSigning ¶ added in v0.7.0
func NormalizeSigning(profiles []SigningProfile) []SigningProfile
NormalizeSigning canonicalizes `requires` values (alias resolution) and synthesizes the implicit `legacy` profile, so a target with no signing_profile has a single, uniform compile path (never a parallel legacy branch). Idempotent.
type StageConfig ¶ added in v0.7.0
StageConfig wires a binary build's output into a docker build's context. From names the binary build (its id); As is the destination path within the context, with {arch}/{os} placeholders substituted using Docker's naming (e.g. "app-{arch}" → "app-amd64") so a multi-arch copy-pre-built Dockerfile resolves per platform.
type StateDir ¶ added in v0.7.0
type StateDir struct {
Type string `yaml:"type,omitempty"` // "volume" | "host_path"
Name string `yaml:"name,omitempty"` // volume name (type: volume)
Path string `yaml:"path,omitempty"` // absolute path (type: host_path)
}
StateDir locates the durable, operator-chosen home for persistent signing material — outside the build tree so it is never cleared, committed, or baked.
func (StateDir) Configured ¶ added in v0.7.0
Configured reports whether a state dir is declared at all.
type StencilDef ¶ added in v0.8.0
type StencilDef struct {
ID string `yaml:"-"` // set from the stencils map key
// SOURCE × RENDER.
Type string `yaml:"type,omitempty"` // producer; empty = inline
Render string `yaml:"render,omitempty"` // form: badge (default) | shield | image | table | list | kv | versions | raw
// ── inline badge / shield areas ──
Label string `yaml:"label,omitempty"` // left text (defaults to id); also props alt override
Message string `yaml:"message,omitempty"` // right value (templates)
Color string `yaml:"color,omitempty"` // hex or "auto"
Font string `yaml:"font,omitempty"` // badge font override
FontSize int `yaml:"font_size,omitempty"` // badge font size override
Output string `yaml:"output,omitempty"` // SVG output path (badge generation)
Link string `yaml:"link,omitempty"` // clickable URL
Logo string `yaml:"logo,omitempty"` // shields.io logo / props logo
LogoColor string `yaml:"logo_color,omitempty"`
LabelColor string `yaml:"label_color,omitempty"`
Shield string `yaml:"shield,omitempty"` // shields.io path (render: shield)
// ── text (the dumb markdown stencil: facts + {id} stencil embeds, no logic) ──
// llm shares body: — there it is the composed INPUT (inject {ci-detail} etc.
// and write the ask inline; no separate prompt slot).
Body string `yaml:"body,omitempty"`
// ── llm (AI stencil: composed body × llms: backend → markdown) ──
LLM string `yaml:"llm,omitempty"` // llms: entry id (the backend reference)
// ── component ──
Spec string `yaml:"spec,omitempty"`
// ── include ──
Path string `yaml:"path,omitempty"`
// ── contents (build manifest) / ci (run-state producers) ──
Build string `yaml:"build,omitempty"`
Source string `yaml:"source,omitempty"`
Section string `yaml:"section,omitempty"`
// Limit caps a ci producer's rows (self-bounding: excess becomes "+K more").
Limit int `yaml:"limit,omitempty"`
// contents renderer form lives on the RENDER axis (render:), not a separate
// renderer: key — one form vocabulary (badges|table|list|kv|versions).
Columns []string `yaml:"columns,omitempty"`
OutputFile string `yaml:"output_file,omitempty"`
Wrap string `yaml:"wrap,omitempty"`
Summary string `yaml:"summary,omitempty"`
// ── named-producer coordinate override (props) ──
Repo string `yaml:"repo,omitempty"` // repos: id whose coordinates the producer uses (default: publish-origin)
// ── props (github-*, goreportcard, …) ──
Params map[string]string `yaml:"params,omitempty"`
Style string `yaml:"style,omitempty"`
// ── k8s-inventory ──
CatalogPath string `yaml:"catalog,omitempty"`
}
StencilDef is one entry in the top-level stencils: library — a named, reusable markdown element with variable fill, embeddable as {id} anywhere SF composes audience text (scribe file regions, narrate, release bodies). Its shape is SOURCE (type:) × RENDER (render:): an inline def (no type) renders a badge (default) or shield; a named producer (type: goreportcard, github-*, contents, include, text, component, k8s-inventory) renders through the matching module. The id (map key) is the {id} embed target and the default label.
func ShippedStencil ¶ added in v0.8.0
func ShippedStencil(id, modality string) (StencilDef, bool)
ShippedStencil returns SF's built-in stencil definition for id under the given lifecycle modality, if one exists. Callers must check user stencils FIRST — shadowing a shipped id is the override mechanism (redefine `changelog` with knobs — {type: ci, limit: 5} — and every {changelog} embed picks it up).
func (StencilDef) EffectiveKind ¶ added in v0.8.0
func (c StencilDef) EffectiveKind() string
EffectiveKind maps (Type, Render) to the render module used for this stencil. It is the discriminator the runtime dispatches on when resolving a {id} embed to markdown.
func (StencilDef) HasGeneration ¶ added in v0.8.0
func (c StencilDef) HasGeneration() bool
HasGeneration reports whether this stencil produces an SVG badge (an inline badge with an output path).
func (StencilDef) LabelOrID ¶ added in v0.8.0
func (c StencilDef) LabelOrID() string
LabelOrID returns the badge/alt label, defaulting to the stencil id.
func (StencilDef) ToBadgeSpec ¶ added in v0.8.0
func (c StencilDef) ToBadgeSpec() BadgeSpec
ToBadgeSpec extracts the SVG-generation fields.
type StringOrList ¶ added in v0.7.0
type StringOrList []string
StringOrList unmarshals a YAML scalar OR a sequence of strings into []string.
func (StringOrList) First ¶ added in v0.8.0
func (s StringOrList) First() string
First returns the first element, or "" if empty — for single-value consumers of a field that is now a list (e.g. a metadata description variant).
func (*StringOrList) UnmarshalYAML ¶ added in v0.7.0
func (s *StringOrList) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML accepts a bare scalar (coerced to a one-element list) or a sequence. Anything else is an error.
type SummaryFilter ¶ added in v0.5.0
type SummaryFilter struct {
StripPhrases []string `yaml:"strip_phrases,omitempty"`
StripRegex []string `yaml:"strip_regex,omitempty"`
}
SummaryFilter strips content from commit subjects.
type SyncConfig ¶ added in v0.4.1
type SyncConfig struct {
Branches *FacetSpec `yaml:"branches,omitempty"`
Tags *FacetSpec `yaml:"tags,omitempty"`
Releases *FacetSpec `yaml:"releases,omitempty"`
// contains filtered or unexported fields
}
SyncConfig is the per-facet replication spec on a mirror repo (repos.<id>.sync).
func (SyncConfig) Active ¶ added in v0.8.0
func (s SyncConfig) Active() bool
Active reports whether any facet is synced.
func (SyncConfig) IsLegacyForm ¶ added in v0.8.0
func (s SyncConfig) IsLegacyForm() bool
IsLegacyForm reports whether the sync block was written in the retired git/releases/docs bool form (translated on load).
func (SyncConfig) SyncsGit ¶ added in v0.8.0
func (s SyncConfig) SyncsGit() bool
SyncsGit reports whether this repo replicates git refs (branches or tags).
func (SyncConfig) SyncsReleases ¶ added in v0.8.0
func (s SyncConfig) SyncsReleases() bool
SyncsReleases reports whether this repo replicates releases.
func (*SyncConfig) UnmarshalYAML ¶ added in v0.8.0
func (s *SyncConfig) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML accepts the whole-hog scalar (sync: exact), the per-facet map, and the retired git/releases/docs bool form (translated with behavior preserved).
type SyncTopology ¶ added in v0.8.0
type SyncTopology struct {
PrimaryID string `json:"primary_id"`
Mirrors []MirrorSync `json:"mirrors,omitempty"`
}
SyncTopology is the replication topology: the primary source and each mirror's per-facet sync summary. It recovers the one-glance scannability that per-repo sync placement trades away (the resolved-view precedent).
func BuildSyncTopology ¶ added in v0.8.0
func BuildSyncTopology(cfg *Config) SyncTopology
BuildSyncTopology derives the replication topology from the resolved config.
type TagConfig ¶ added in v0.5.0
type TagConfig struct {
Preset string `yaml:"preset,omitempty"`
Defaults TagDefaults `yaml:"defaults"`
Message TagMessage `yaml:"message"`
// Render controls tag change-log rendering (default DefaultTagPresentation; a
// partial render: block overlays those defaults).
Render TagPresentation `yaml:"render,omitempty"`
}
TagConfig holds workflow defaults for the tag planner.
func DefaultTagConfig ¶ added in v0.5.0
func DefaultTagConfig() TagConfig
DefaultTagConfig returns sensible defaults.
type TagDefaults ¶ added in v0.5.0
type TagDefaults struct {
Target string `yaml:"target"` // default ref to tag (default: HEAD)
Preview bool `yaml:"preview"` // show preview before creating
RequireApproval bool `yaml:"require_approval"` // require interactive approval
Push bool `yaml:"push"` // push after creation
}
TagDefaults controls default tag planning behavior.
type TagMessage ¶ added in v0.5.0
type TagMessage struct {
Mode string `yaml:"mode"` // auto | prompt_if_missing | require_manual
EmptyStrategy string `yaml:"empty_strategy"` // prompt | fail | allow_empty
}
TagMessage controls tag annotation message behavior.
type TagPresentation ¶ added in v0.5.0
type TagPresentation struct {
MaxEntries int `yaml:"max_entries"`
GroupByType bool `yaml:"group_by_type"`
Style string `yaml:"style"` // concise | explanatory | technical
IncludeReleaseVisibleOnly bool `yaml:"include_release_visible_only"`
CollapseSimilar bool `yaml:"collapse_similar"`
}
TagPresentation controls tag annotation rendering (tagging.render).
func DefaultTagPresentation ¶ added in v0.8.0
func DefaultTagPresentation() TagPresentation
DefaultTagPresentation is the default tagging.render policy.
type TagSourceConfig ¶ added in v0.6.0
type TagSourceConfig struct {
// ID is the unique identifier (e.g. "stable", "prerelease").
// Referenced by branch_builds[].base_from and target.when.git_tags.
ID string `yaml:"id"`
// Pattern is the regex that identifies tags belonging to this source.
// e.g., "^v?\\d+\\.\\d+\\.\\d+$"
Pattern string `yaml:"pattern"`
}
TagSourceConfig is a named tag pattern used for version lineage candidates.
type TargetCondition ¶
type TargetCondition struct {
// Branches lists branch filters. Each entry is a policy name or "re:<regex>".
// Empty = no branch filtering.
Branches []string `yaml:"branches,omitempty"`
// GitTags lists git tag filters. Each entry is a policy name or "re:<regex>".
// Empty = no tag filtering.
GitTags []string `yaml:"git_tags,omitempty"`
// Events lists CI event type filters.
// Supported: push, tag, release, schedule, manual, pull_request, merge_request.
// Empty = no event filtering.
Events []string `yaml:"events,omitempty"`
// Forges restricts this target to specific CI forges by provider name
// (github, gitlab, gitea, forgejo). Empty = every forge. Use it when a
// registry is reachable/credentialed on some forges but not others — e.g. a
// private mirror that only resolves from the self-hosted GitLab runner, or a
// ghcr push that only makes sense on GitHub Actions.
Forges []string `yaml:"forges,omitempty"`
// Outcomes gates on the RUN outcome (success | failure | warning) — the
// notification dimension of the one when: grammar ("failures, but only on
// main" composes with branches:/events:). Empty = every outcome. Only valid
// on notifications: a publish target's when: is evaluated for eligibility
// BEFORE an outcome exists, so outcomes: there is a validation error.
Outcomes []string `yaml:"outcomes,omitempty"`
}
TargetCondition defines routing conditions for a target. All non-empty fields must match (AND logic).
type TargetConfig ¶
type TargetConfig struct {
// ID is the unique identifier for this target (logging, status, enable/disable).
ID string `yaml:"id"`
// Kind is the target type. Determines which fields are valid.
Kind string `yaml:"kind"`
// Build references a BuildConfig.ID. Required for kind: registry.
Build string `yaml:"build,omitempty"`
// When specifies routing conditions for this target: a single condition-set,
// or a list of them (OR — the target fires if ANY matches). See WhenConditions.
When WhenConditions `yaml:"when,omitempty"`
// RunFrom gates mutation to declared execution origins.
// e.g. ["primary"] — only mutate when running from sources.primary.
// Empty = no restriction (backward compat).
RunFrom RunFromConfig `yaml:"run_from,omitempty"`
// SelectTags enables CLI filtering via --select.
SelectTags []string `yaml:"select_tags,omitempty"`
// Registry references registries[].id for registry/metadata targets. Accepts
// a single id (registry: harbor) or a list (registry: [dockerhub, ghcr, harbor]) —
// a list fans the target across registries: expandMultiRegistryTargets splits it
// into one single-registry target per id at load, so resolution/execution always
// sees exactly one registry. When set, URL/Provider/Path/Credentials resolve from
// the registry entry. Path can still be overridden on the target.
Registry StringOrList `yaml:"registry,omitempty"`
// SigningProfile references a signing.profiles[].id — the trust profile this
// target signs under. Empty = the synthesized `legacy` profile (key-signing,
// inert unless a key resolves). Reference-by-id, same pattern as Registry.
SigningProfile string `yaml:"signing_profile,omitempty"`
// URL is the registry/forge hostname (kind: registry, metadata, release).
URL string `yaml:"url,omitempty"`
// Provider is the vendor type for auth and API behavior.
// Registry: docker, ghcr, gitlab, jfrog, harbor, quay, gitea, generic.
// Release: github, gitlab, gitea.
// If omitted on registry, inferred from URL.
Provider string `yaml:"provider,omitempty"`
// Path is the image path within the registry (kind: registry).
Path string `yaml:"path,omitempty"`
// Credentials is the env var prefix for authentication.
// Resolution: try {PREFIX}_TOKEN first, else {PREFIX}_USER + {PREFIX}_PASS.
Credentials string `yaml:"credentials,omitempty"`
// Description is the short project description/tagline. A scalar for kind:
// registry; kind: metadata accepts a LIST of length-tiered variants
// (the engine picks the longest that fits each destination's cap).
Description StringOrList `yaml:"description,omitempty"`
// Retention controls cleanup of old tags/releases.
// Structured only in v2 (no scalar shorthand).
Retention *RetentionPolicy `yaml:"retention,omitempty"`
// Tags are tag templates resolved against version info (kind: registry).
// e.g., ["{version}", "{major}.{minor}", "latest"]
Tags []string `yaml:"tags,omitempty"`
// NativeScan enables post-push vulnerability scanning via the registry's own built-in scanner.
// Distinct from StageFreight's own scan pipeline (Trivy/Grype run by StageFreight itself).
// Currently supported: Harbor (triggers Harbor's built-in Trivy after each push).
// No-op for Docker Hub, GHCR, Quay, JFrog, and other providers.
// Best-effort — scan failures warn but do not fail the build.
// Push success does not imply scan success; results appear in the registry UI only.
NativeScan bool `yaml:"native_scan,omitempty"`
// Readme is the long markdown 'project page' body (registries only: Docker Hub Overview,
// Harbor Info, JFrog README, Quay Description). On a forge the README is committed → N/A.
Readme string `yaml:"readme,omitempty"`
// Website is the project's external site URL (forges: GitHub, Gitea/Forgejo).
Website string `yaml:"website,omitempty"`
// Topics are discovery tags (forges: GitHub, GitLab, Gitea). Authored freely; the engine
// normalizes to lowercase-hyphenated per destination and warns on any transform.
Topics []string `yaml:"topics,omitempty"`
// Logo is a path to the project avatar image (project-scoped forges: GitLab, Gitea/Forgejo);
// synced idempotently. Org-scoped logos (GitHub, Docker Hub) are out of scope.
Logo string `yaml:"logo,omitempty"`
// SpecFiles lists component spec file paths (kind: gitlab-component).
SpecFiles []string `yaml:"spec_files,omitempty"`
// Catalog enables GitLab Catalog registration (kind: gitlab-component).
Catalog bool `yaml:"catalog,omitempty"`
// Notes names the stencil (a type: text body in stencils:) that composes
// this release's notes document (kind: release). An explicit reference —
// different targets may name different stencils. Empty = SF's shipped
// default body.
Notes string `yaml:"notes,omitempty"`
// Aliases are rolling git tag aliases (kind: release).
// e.g., ["{version}", "{major}.{minor}", "latest"]
// Named "aliases" to avoid collision with Tags (image tags) and git_tags (policy filters).
Aliases []string `yaml:"aliases,omitempty"`
// Tag is the immutable identity pattern for a release channel (kind: release).
// Distinct from Aliases (rolling): Tag names one immutable release per build, e.g.
// "dev-{sha:8}". Resolved against version info like Aliases ({version}, {sha:8}, ...).
// When the triggering event is not itself a ref (a branch push), the release runner
// mints this tag so the channel release has a stable anchor. Empty = no channel tag.
Tag string `yaml:"tag,omitempty"`
// Type is the semantic release classification (kind: release):
//
// type: latest — the stable, "Latest" release (GitHub: make_latest=true)
// type: prerelease — a pre-release (never Latest)
// type: unspecified — explicit default/auto (declarative GitOps; same as omitting)
//
// Omitting the field is identical to "unspecified": the type is inferred from the
// version (a semver prerelease suffix ⇒ prerelease) and the legacy `prerelease` flag.
// Each forge lowers the intent to what it can express (GitHub: prerelease+make_latest;
// Gitea: prerelease; GitLab: a plain release; Azure: n/a).
Type string `yaml:"type,omitempty"`
// Prerelease marks the forge release as a pre-release (kind: release). DEPRECATED:
// prefer `type: prerelease`. Still honored when `type` is unset/unspecified.
Prerelease bool `yaml:"prerelease,omitempty"`
// ProjectID is the "owner/repo" or numeric ID for remote forge targets (kind: release).
ProjectID string `yaml:"project_id,omitempty"`
// Repos names the destination repos[].id for a kind: release target. The repo
// with role primary is the canonical release (authored via the git remote); every
// other named repo gets an authored copy (release + assets). Forge identity for
// each is resolved from its repos[] entry. A repo reaches releases via a target's
// repos: XOR its sync.releases facet — never both (config-time XOR).
Repos StringOrList `yaml:"repos,omitempty"`
// Archives references a binary-archive target ID (kind: release and generic-package).
Archives string `yaml:"archives,omitempty"`
// BinaryName overrides the binary name inside the archive (kind: binary-archive).
// Auto-detected from referenced build if omitted.
BinaryName string `yaml:"binary_name,omitempty"`
// Format is the archive format: "tar.gz", "zip", "auto", or "binary" (kind:
// binary-archive). "auto" picks zip for windows, tar.gz for everything else (default).
// "binary" is a passthrough: the build's single-file output is carried as the
// distributable as-is, NOT re-archived — for a build whose output is already packaged
// (e.g. a kind: command build that emits its own tarball or a raw binary you want
// uploaded unwrapped), so no double-archiving occurs.
Format string `yaml:"format,omitempty"`
// Name is the archive filename template (kind: binary-archive).
// Supports: {id}, {version}, {os}, {arch}. e.g., "{id}-{version}-{os}-{arch}".
Name string `yaml:"name,omitempty"`
// Include lists extra files to bundle into the archive (kind: binary-archive).
// e.g., ["README.md", "LICENSE"]
Include []string `yaml:"include,omitempty"`
// Checksums generates a SHA256SUMS file alongside archives (kind: binary-archive).
Checksums bool `yaml:"checksums,omitempty"`
// Repo references a repos[].id (kind: generic-package). The forge identity
// (provider, url, project, credentials) is resolved from the repo; the package
// is published to that forge's generic package registry.
Repo string `yaml:"repo,omitempty"`
// Package is the generic package name (kind: generic-package).
// Defaults to the repo project's basename if empty.
Package string `yaml:"package,omitempty"`
// Version is the immutable package version pattern (kind: generic-package).
// Resolved against version info like Aliases ({version}, {sha:8}, ...), e.g.
// "dev-{sha:8}". Published once, never overwritten. Distinct from a release Tag
// (a git ref): this names a package *version*, not a git tag. Required — every
// rolling Alias must have an immutable Version behind it.
Version string `yaml:"version,omitempty"`
// Project is the Cloudflare Pages project name (provider: cloudflare). Default:
// the target id. Cloudflare requires lowercase letters, digits, and hyphens,
// 1–58 chars, no leading/trailing hyphen — validated at load. Ignored by the
// github provider (which deploys to the gh-pages branch of the repo).
Project string `yaml:"project,omitempty"`
// Dir publishes a repo directory directly instead of a build's output tree
// (kind: pages). Exactly one of Build or Dir must be set.
Dir string `yaml:"dir,omitempty"`
// Exclude drops matching paths from the publish workspace before deploy
// (kind: pages). Globs, applied after extraction.
Exclude []string `yaml:"exclude,omitempty"`
// Domain is the custom domain(s) (kind: pages). Accepts a bare scalar or a list:
//
// domain: precisionplanit.com
// domain: [precisionplanit.com, prplanit.com]
//
// Cloudflare attaches every listed domain to the project (each auto-wires DNS).
// GitHub Pages serves a single custom domain, so a list is rejected at load; the
// one entry is written as the CNAME.
Domain StringOrList `yaml:"domain,omitempty"`
// BasePath is the URL path the site is served under (kind: pages). Inferred per
// provider (Cloudflare "/", GitHub project "/<repo>/") and fed into the build.
BasePath string `yaml:"base_path,omitempty"`
// Versioning controls multi-version publishing (kind: pages). P1 accepts only
// mode: replace; mode: keep is reserved for phase 2 and rejected.
Versioning *PagesVersioning `yaml:"versioning,omitempty"`
}
TargetConfig defines a distribution target or side-effect. Each target has a unique ID and a kind that determines which fields are valid.
This is a discriminated union keyed by Kind. Only fields relevant to the kind should be set — validated at load time.
Target kinds:
- registry: Push image tags to a container registry (requires build reference)
- metadata: Push project identity (description/readme/website/topics/logo) to registries + forge repos
- gitlab-component: Publish to GitLab CI component catalog (standalone)
- release: Create forge release + rolling git tags (standalone)
- generic-package: Publish archives to a forge generic package registry (standalone)
- pages: Deploy a static-site build's output to Cloudflare/GitHub Pages (build XOR dir)
type TestConfig ¶ added in v0.7.0
type TestConfig struct {
Preset string `yaml:"preset,omitempty"`
Enabled bool `yaml:"enabled"`
Auto *bool `yaml:"auto,omitempty"` // nil ⇒ true
Suites OrderedTestSuites `yaml:"suites,omitempty"`
}
TestConfig is the test subsystem. Auto-on by default: when Enabled and no suites are declared, a default suite is synthesized per builder from build metadata (unless Auto is explicitly false).
func DefaultTestConfig ¶ added in v0.7.0
func DefaultTestConfig() TestConfig
DefaultTestConfig is auto-on with no declared suites (synthesis derives the default suite from the configured builds).
func (TestConfig) AutoSynthesize ¶ added in v0.7.0
func (t TestConfig) AutoSynthesize() bool
AutoSynthesize reports whether a default suite should be synthesized from build metadata when the operator declared none. Defaults to true.
type TestSuite ¶ added in v0.7.0
type TestSuite struct {
ID string `yaml:"id"`
Tool TestTool `yaml:"tool"`
Gate Gate `yaml:"gate,omitempty"` // default: perform
From string `yaml:"from,omitempty"` // module/crate dir when not at repo root (e.g. dd-ui's api/)
Args []string `yaml:"args,omitempty"` // raw passthrough escape hatch
Command string `yaml:"command,omitempty"`
// ── Go (native `go test` flag projections) ──────────────────────────────
Packages []string `yaml:"packages,omitempty"` // ./p/... (default ./...)
Tags []string `yaml:"tags,omitempty"` // -tags a,b
Run string `yaml:"run,omitempty"` // -run <regex>
Timeout string `yaml:"timeout,omitempty"` // -timeout <d>
Race *bool `yaml:"race,omitempty"` // -race
Coverage *bool `yaml:"coverage,omitempty"` // -coverprofile
CoverageMin *float64 `yaml:"coverage_min,omitempty"` // gate: fail the suite if statement coverage < this %
// ── Rust (native `cargo test` flag projections) ─────────────────────────
Workspace *bool `yaml:"workspace,omitempty"` // --workspace
Features []string `yaml:"features,omitempty"` // --features a,b
Tests []string `yaml:"tests,omitempty"` // --test <name>
Release *bool `yaml:"release,omitempty"` // --release
Nextest *bool `yaml:"nextest,omitempty"` // cargo nextest run
// ── Python (native `pytest` flag projections) ───────────────────────────
// Selection reuses the shared fields whose meaning is identical across
// dialects: Packages → positional test paths, Run → -k <expr> (pytest's
// keyword filter, the analogue of go's -run), Coverage/CoverageMin → --cov.
Markers []string `yaml:"markers,omitempty"` // -m <marker>
}
TestSuite is one behavioral-verification suite. Typed fields are declarative projections of the native flag a developer already types (`-race`, `-tags`, `--workspace`, `--features`), so the YAML reads as the command. Fields are type-specific — Go and Rust have different selection spaces and are NOT forced through one shared vocabulary. `Args` is the explicit, intentionally-unsafe escape hatch (bypasses the typed guarantees); `Command` (with `type: script`) replaces the runner entirely.
func (TestSuite) EffectiveGate ¶ added in v0.7.0
EffectiveGate returns the suite's gate, defaulting to perform (the strict, zero-wiring tier) when unset.
type TestTool ¶ added in v0.7.0
type TestTool string
TestTool is the test toolchain/dialect a suite uses — how its command is constructed, NOT where it runs (it is not a CI "runner"). `go`/`rust`/`python` are first-class typed (native-flag projection + builder-derived defaults); `script` is the intentionally-less-structured raw escape hatch. Future: `container`, `compose`.
type ToolConstraint ¶ added in v0.7.0
type ToolConstraint struct {
Constraint string `yaml:"version,omitempty"`
}
ToolConstraint declares the acceptable version(s) for a single tool. The YAML key is `version` — the Cargo/Go convention — and its VALUE is a version requirement, not necessarily one exact version: "1.26.4" is exact, "1.26.x" is a line. It is pure operator INTENT. The machine-maintained RESOLUTION of that intent — the concrete version a wildcard locked to, plus its artifact digest — lives in .stagefreight/toolchains.lock, NOT here: the config is the Cargo.toml, the lock is the Cargo.lock. The Go field is named Constraint because the value is a requirement (the same reason Cargo models a `version` field as a VersionReq), even though the surface key is `version`.
func (*ToolConstraint) UnmarshalYAML ¶ added in v0.7.0
func (t *ToolConstraint) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML accepts two input forms and normalizes them to the internal Constraint — it answers only "what did the user write", performing no semantic validation:
go: 1.26.x # scalar shorthand
go: {version: 1.26.x} # explicit
type ToolchainConfig ¶ added in v0.6.0
type ToolchainConfig map[string]ToolConstraint
ToolchainConfig is the want: map inside the toolchains section (tool name → desired version constraint).
func (*ToolchainConfig) UnmarshalYAML ¶ added in v0.7.0
func (c *ToolchainConfig) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML decodes the tool→constraint mapping directly, naming the offending tool on a parse error. The tools block IS the map — the retired `desired:` wrapper is gone (a legacy `desired: …` key parses as a tool with no version and fails validation).
type ToolchainSection ¶ added in v0.10.0
type ToolchainSection struct {
// Want is the tool→constraint map — the versions the operator WANTS (constraints, not
// necessarily exact pins); the lock records what resolution GOT. Mirrors the internal
// ToolchainDesired vocabulary. Authoritative, not a hint: a constraint that
// fails to resolve fails the run, no fallback. Top-level in .stagefreight.yml
// because toolchains are execution substrate (security scanning, signing, linting,
// gitops), not CI-specific.
Want ToolchainConfig `yaml:"want,omitempty"`
// Retention governs how many resolved versions of each tool are RETAINED on the
// runner (keep_last newest per tool; unset = engine default 2). The pinned
// constraint's resolved version and the lock's resolution are always protected —
// retention rotates superseded residue, never declared intent.
Retention RetentionPolicy `yaml:"retention,omitempty"`
}
ToolchainSection is the toolchains: block — a wrapper pairing the tool→constraint map (want:) with the versions' lifecycle policy (retention:), following the keyed-map-plus-sibling-policy pattern (scribe: files+commit, governance: profiles). The map moved under want: in the wrapper flag-day: retention is POLICY about the installed versions, not a tool, so it must not live inside the tool namespace.
func (*ToolchainSection) UnmarshalYAML ¶ added in v0.10.0
func (s *ToolchainSection) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML decodes the toolchains section — the wrapper shape ONLY (clean-break flag-day, no legacy acceptance). The retired flat tool→constraint shape fails with a targeted migration hint naming the offending key, never a bare unknown-field error.
type TrailerFilter ¶ added in v0.5.0
type TrailerFilter struct {
StripKeys []string `yaml:"strip_keys,omitempty"`
}
TrailerFilter strips commit trailers/footers.
type VolumeProtection ¶ added in v0.5.0
type VolumeProtection struct {
Named *bool `yaml:"named,omitempty"` // protect all named volumes
}
VolumeProtection defines which volumes are protected from pruning.
type WhenConditions ¶ added in v0.8.0
type WhenConditions []TargetCondition
WhenConditions is a target's routing gate: one condition-set, or a list of them combined with OR — the target fires if ANY condition matches. It accepts either a single condition map (when: { ... }) or a sequence of them (when: [ {...}, {...} ]). An empty/absent when: is unconditional (eligible in every context).
All when: interpretation flows through TargetEligibility (target_match.go); this type only models the shape.
func (*WhenConditions) UnmarshalYAML ¶ added in v0.8.0
func (w *WhenConditions) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML accepts a single condition map OR a sequence of condition maps.
type WorktreeOutput ¶ added in v0.7.0
type WorktreeOutput struct {
BuildID string
Output OutputSpec
}
WorktreeOutput pairs a build with one of its outputs that lands in the working tree.
type WorktreeSpec ¶ added in v0.7.0
type WorktreeSpec struct {
Set bool // whether worktree was present and truthy
Path string // explicit landing path; empty means "land at the output's Source"
}
WorktreeSpec is an output's optional landing into the git working tree during Narrate. It accepts a bool or a path: `worktree: true` lands the output at its Source path; `worktree: <path>` lands it there instead (a clean rename); `worktree: false` / absent leaves it as a pure artifact. The runner materializes every landed output at the start of Narrate — before badges/patches/commit — so downstream config deals only in paths.
func (WorktreeSpec) MarshalYAML ¶ added in v0.7.0
func (w WorktreeSpec) MarshalYAML() (interface{}, error)
MarshalYAML renders back to the scalar form (`true`/`false` or the path) so `config render` stays clean.
func (*WorktreeSpec) UnmarshalYAML ¶ added in v0.7.0
func (w *WorktreeSpec) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML accepts either a bool (`true`/`false`) or a path string.
Source Files
¶
- ansible.go
- authority.go
- badge.go
- build.go
- buildcache.go
- ci.go
- commit.go
- conditions.go
- config.go
- dependency.go
- docker.go
- docker_lifecycle.go
- enums.go
- event.go
- forge_host.go
- forges.go
- git.go
- gitops.go
- glossary.go
- identity_map.go
- identity_subs.go
- lifecycle.go
- lint.go
- llm.go
- manifest.go
- match.go
- metadata.go
- migrate.go
- mode.go
- narrate.go
- normalize.go
- notifications.go
- orgs.go
- presentation.go
- preset.go
- producer_coords.go
- publish.go
- release.go
- report.go
- resolve.go
- retention.go
- scoped.go
- scribe.go
- security.go
- signing.go
- signing_setup.go
- sources.go
- stencil.go
- stencil_defaults.go
- sync.go
- tag.go
- target.go
- target_match.go
- test.go
- toolchain.go
- units.go
- validate.go
- versioning.go
- when.go