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
- func (c *Config) ApplyStencilStoreDefaults()
- func (c *Config) DriftedPresets() []presetref.Outcome
- func (c *Config) Mode() LifecycleMode
- func (c *Config) PresetOutcomes() []presetref.Outcome
- func (c *Config) RefreshedPresets() []presetref.Outcome
- func (c *Config) SetPresetOutcomes(o []presetref.Outcome)
- func (c *Config) StencilsByID() map[string]StencilDef
- func (c *Config) WorktreeOutputs() []WorktreeOutput
- 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 GroupSource
- type HostCleanupConfig
- type IDMap
- type ImageProtection
- type ImagePrunePolicy
- type InventoryCategory
- type InventoryConfig
- type InventoryGroups
- 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 PolicyPresetLoader
- type PresetLoader
- 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 ( DefaultChangesLimit = 20000 DefaultChangelogLimit = 40000 )
Release-note fact bounds, in characters, when a target declares none.
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"`
// Label is an optional human display name for this build's image in the release
// notes / README "Image Availability" table group header (e.g. "Backend", "Login v2").
// Purely presentational; when empty the group header falls back to the image name.
// Generic — no per-app defaults.
Label string `yaml:"label,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"`
// Secrets are id → in-repo file path, passed as --secret id=<id>,src=<path>.
// A build arg is baked into the image and readable from its history; a secret is
// mounted for one RUN and leaves nothing behind. Use it for a credential, and for
// an input a Dockerfile expects this way — upstream frappe_docker takes its app
// list as a secret rather than a build arg, for instance.
Secrets map[string]string `yaml:"secrets,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
Categories []InventoryCategory
Groups GroupSource
}
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"`
// 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"`
// contains filtered or unexported fields
}
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 LoadOffline ¶ added in v0.11.0
LoadOffline loads a config resolving sourced presets from the retained cache only, never the network.
For verifying a render against the cache that ships WITH it — governance checking a satellite's config before distributing it. Resolving live there would ask the wrong question (does the source answer right now) instead of the one that matters (is what we are about to hand over self-sufficient), and would fetch every reference once per governed repo.
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) DriftedPresets ¶ added in v0.11.0
DriftedPresets returns the references whose source served content differing from what was retained. This is the REPORTING view: it answers whether policy content changed.
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) PresetOutcomes ¶ added in v0.11.0
PresetOutcomes reports how each sourced preset reference resolved on this load. Empty when every reference was local, or when nothing was sourced.
func (*Config) RefreshedPresets ¶ added in v0.11.0
RefreshedPresets returns the references whose retained copy THIS run wrote — the set a satellite must carry back. Not the same question as DriftedPresets: a copy governance never seeded is written without differing from anything, and a pin mismatch the operator chose to resolve from the source is a write they asked for. Either way the run produced a retained copy, and one that is never committed leaves the tree dirty.
func (*Config) SetPresetOutcomes ¶ added in v0.11.0
SetPresetOutcomes records how sourced references resolved. The loader sets this on the config it builds; exported so a caller that resolves presets itself can hand the result on, and so the behaviour that depends on it is reachable from a test.
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"`
IngressClasses []string `yaml:"ingress_classes"` // Ingress spec.ingressClassName
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"`
// Submodules requests that CI check out submodules. A pipeline that clones without
// them leaves the submodule directory empty, and the build fails on a missing file
// rather than on anything to do with the checkout — so this is declared, not guessed.
Submodules bool `yaml:"submodules,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"`
// Categories groups the cluster's namespaces into app inventory sections.
Categories []InventoryCategory `yaml:"categories,omitempty"`
// Inventory configures how the app inventory reads the cluster.
Inventory InventoryConfig `yaml:"inventory,omitempty"`
// 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 GroupSource ¶ added in v0.14.0
type GroupSource struct {
Annotation string `yaml:"annotation,omitempty"`
Label string `yaml:"label,omitempty"`
Field string `yaml:"field,omitempty"`
}
GroupSource reads a group from the Services, HTTPRoutes and Ingresses that expose an app: an annotation or a label, and when the value is a YAML mapping, one field of it.
func (GroupSource) Set ¶ added in v0.14.0
func (g GroupSource) Set() bool
Set reports whether a group source is configured.
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 InventoryCategory ¶ added in v0.14.0
type InventoryCategory struct {
Name string `yaml:"name"`
// Tier declares what the namespaces' workloads are: app, platform or hidden. Left
// empty, discovery infers it per workload.
Tier string `yaml:"tier,omitempty"`
Namespaces []string `yaml:"namespaces"`
}
InventoryCategory is one section of the app inventory. Sections render alphabetically.
type InventoryConfig ¶ added in v0.14.0
type InventoryConfig struct {
Groups InventoryGroups `yaml:"groups,omitempty"`
}
InventoryConfig is gitops.<cluster>.inventory.
type InventoryGroups ¶ added in v0.14.0
type InventoryGroups struct {
From GroupSource `yaml:"from,omitempty"`
}
InventoryGroups names where an app's group is already declared in the cluster, so the inventory reuses it instead of a second declaration. An app with a group is an app, listed under that group; categories: covers apps without one.
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 PolicyPresetLoader ¶ added in v0.11.0
PolicyPresetLoader is an optional PresetLoader capability: resolve a reference under the mismatch policy declared beside it. A loader without it resolves under the default, which is to stop.
type PresetLoader ¶ added in v0.6.0
PresetLoader fetches preset content by path. Implementations: local filesystem, git repo checkout.
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)
// 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"`
// ReleaseDetailMaxRows bounds how many vulnerability rows the "full" detail level
// writes into release notes; the rest are reported as a count. Unset = 100.
//
// "full" means complete within reason, not unbounded: a large image can carry
// thousands of advisories, and every forge caps a release body — GitHub at 125k
// characters, and it rejects an over-long body outright rather than trimming it. The
// rows are written worst-first, so a bound keeps what a reader acts on and drops the
// tail they scroll past. 0 disables the bound and restores the old behaviour.
ReleaseDetailMaxRows *int `yaml:"release_detail_max_rows,omitempty"`
// 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"`
// Include keeps only the inventory items whose name matches one of these globs
// (case-insensitive), ordered as the globs are listed — a curated subset of a
// section that would otherwise print every package the image carries.
Include []string `yaml:"include,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"`
// SecuritySummary attaches the security summary to this release; the summary's
// location is security.output, so this is a yes/no toggle rather than a path.
// RegistryLinks and CatalogLinks attach the published image and catalog links.
//
// Per target, with Notes and Limits, because all four describe what a release
// CONTAINS, and each channel publishes a different document: a dev release cut on
// every push and a stable one carry different evidence. Unset omits the content.
SecuritySummary bool `yaml:"security_summary,omitempty"`
RegistryLinks bool `yaml:"registry_links,omitempty"`
CatalogLinks bool `yaml:"catalog_links,omitempty"`
// Limits bound the release-note facts that grow with the repo, in characters
// (kind: release). Keyed by fact name — changes, changelog — because the body is
// composed from facts by a stencil, so there is no fixed set of sections to name:
// a stencil may omit a fact, reorder them, or use one twice.
//
// Per target because verbosity is a property of the channel, not the project: a dev
// release cut on every push wants a terse changelog where a stable one wants the
// whole thing. Unset uses the engine default; 0 is unbounded.
//
// A bound stops between entries and never inside one, and states the remainder as a
// count — every forge caps a release body, and an over-long one is rejected outright
// rather than trimmed.
Limits map[string]int `yaml:"limits,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
- unused_matchers.go
- validate.go
- versioning.go
- when.go