Documentation
¶
Index ¶
- func BuildOrchestrator(spec *CampaignSpec, campaignFilePath string) (*workflow.WorkflowData, string)
- func ComputeCompiledState(spec CampaignSpec, workflowsDir string) string
- func CreateSpecSkeleton(rootDir, id string, force bool) (string, error)
- func FetchCursorFreshnessFromRepoMemory(cursorGlob string) (cursorPath string, cursorUpdatedAt string)
- func NewCommand() *cobra.Command
- func RenderClosingInstructions() string
- func RenderOrchestratorInstructions(data CampaignPromptData) string
- func RenderProjectUpdateInstructions(data CampaignPromptData) string
- func ValidateProjectUpdatePayload(payload any, expectedProjectURL string, expectedCampaignID string) []string
- func ValidateSpec(spec *CampaignSpec) []string
- func ValidateSpecWithSchema(spec *CampaignSpec) []string
- func ValidateWorkflowsExist(spec *CampaignSpec, workflowsDir string) []string
- type CampaignApprovalPolicy
- type CampaignGovernancePolicy
- type CampaignKPI
- type CampaignMetricsSnapshot
- type CampaignPromptData
- type CampaignRuntimeStatus
- type CampaignSpec
- type CampaignValidationResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildOrchestrator ¶
func BuildOrchestrator(spec *CampaignSpec, campaignFilePath string) (*workflow.WorkflowData, string)
BuildOrchestrator constructs a minimal agentic workflow representation for a given CampaignSpec. The resulting WorkflowData is compiled via the standard CompileWorkflowDataWithValidation pipeline, and the orchestratorPath determines the emitted .lock.yml name.
func ComputeCompiledState ¶
func ComputeCompiledState(spec CampaignSpec, workflowsDir string) string
ComputeCompiledState inspects the compiled state of all workflows referenced by a campaign. It returns:
"Yes" - all referenced workflows exist and are compiled & up-to-date "No" - at least one workflow exists but is missing a lock file or is stale "Missing workflow" - at least one referenced workflow markdown file does not exist "N/A" - campaign does not reference any workflows
func CreateSpecSkeleton ¶
CreateSpecSkeleton creates a new campaign spec YAML file under .github/workflows/ with a minimal skeleton definition. It returns the relative file path created.
func FetchCursorFreshnessFromRepoMemory ¶ added in v0.33.10
func FetchCursorFreshnessFromRepoMemory(cursorGlob string) (cursorPath string, cursorUpdatedAt string)
FetchCursorFreshnessFromRepoMemory finds the latest cursor/checkpoint file matching cursorGlob in the memory/campaigns branch and returns the matched path along with a best-effort freshness timestamp derived from git history.
Errors are treated as "no cursor" rather than failing the command.
func NewCommand ¶
NewCommand creates the `gh aw campaign` command that surfaces first-class campaign definitions from YAML files.
func RenderClosingInstructions ¶ added in v0.33.2
func RenderClosingInstructions() string
RenderClosingInstructions renders the closing instructions
func RenderOrchestratorInstructions ¶ added in v0.33.2
func RenderOrchestratorInstructions(data CampaignPromptData) string
RenderOrchestratorInstructions renders the orchestrator instructions with the given data.
func RenderProjectUpdateInstructions ¶ added in v0.33.2
func RenderProjectUpdateInstructions(data CampaignPromptData) string
RenderProjectUpdateInstructions renders the project update instructions with the given data
func ValidateProjectUpdatePayload ¶ added in v0.34.4
func ValidateProjectUpdatePayload(payload any, expectedProjectURL string, expectedCampaignID string) []string
ValidateProjectUpdatePayload enforces the governed update-project contract.
This validator is intentionally deterministic: - JSON Schema enforces payload shape. - Semantic checks enforce equality constraints that JSON Schema cannot.
payload is expected to be a YAML/JSON-decoded structure (map[string]any, etc.).
func ValidateSpec ¶
func ValidateSpec(spec *CampaignSpec) []string
ValidateSpec performs lightweight semantic validation of a single CampaignSpec and returns a slice of human-readable problems.
It uses JSON schema validation first, then adds additional semantic checks.
func ValidateSpecWithSchema ¶
func ValidateSpecWithSchema(spec *CampaignSpec) []string
ValidateSpecWithSchema validates a CampaignSpec against the JSON schema. Returns a list of validation error messages, or an empty list if valid.
func ValidateWorkflowsExist ¶
func ValidateWorkflowsExist(spec *CampaignSpec, workflowsDir string) []string
ValidateWorkflowsExist checks that all workflows referenced in a campaign spec actually exist in the .github/workflows directory. Returns a list of problems for workflows that don't exist.
Types ¶
type CampaignApprovalPolicy ¶
type CampaignApprovalPolicy struct {
RequiredApprovals int `yaml:"required-approvals,omitempty" json:"required-approvals,omitempty"`
RequiredRoles []string `yaml:"required-roles,omitempty" json:"required-roles,omitempty"`
ChangeControl bool `yaml:"change-control,omitempty" json:"change-control,omitempty"`
}
CampaignApprovalPolicy captures basic approval expectations for a campaign. It is intentionally lightweight and advisory; enforcement is left to workflows and organizational process.
type CampaignGovernancePolicy ¶ added in v0.33.10
type CampaignGovernancePolicy struct {
// MaxNewItemsPerRun caps how many new items (issues/PRs) the launcher should
// add to the Project board per run. 0 means "use defaults".
MaxNewItemsPerRun int `yaml:"max-new-items-per-run,omitempty" json:"max_new_items_per_run,omitempty"`
// MaxDiscoveryItemsPerRun caps how many candidate issues/PRs the launcher
// and orchestrator may scan during discovery in a single run.
// 0 means "use defaults".
MaxDiscoveryItemsPerRun int `yaml:"max-discovery-items-per-run,omitempty" json:"max_discovery_items_per_run,omitempty"`
// MaxDiscoveryPagesPerRun caps how many pages of results the launcher and
// orchestrator may fetch in a single run.
// 0 means "use defaults".
MaxDiscoveryPagesPerRun int `yaml:"max-discovery-pages-per-run,omitempty" json:"max_discovery_pages_per_run,omitempty"`
// OptOutLabels is a list of labels that opt an issue/PR out of campaign
// tracking. Items with any of these labels should be ignored by launcher/
// orchestrator.
OptOutLabels []string `yaml:"opt-out-labels,omitempty" json:"opt_out_labels,omitempty"`
// DoNotDowngradeDoneItems prevents moving Project status backwards (e.g.
// Done -> In Progress) if the underlying issue/PR is reopened.
DoNotDowngradeDoneItems *bool `yaml:"do-not-downgrade-done-items,omitempty" json:"do_not_downgrade_done_items,omitempty"`
// MaxProjectUpdatesPerRun controls the update-project safe-output maximum
// for generated coordinator workflows. 0 means "use defaults".
MaxProjectUpdatesPerRun int `yaml:"max-project-updates-per-run,omitempty" json:"max_project_updates_per_run,omitempty"`
// MaxCommentsPerRun controls the add-comment safe-output maximum for
// generated coordinator workflows. 0 means "use defaults".
MaxCommentsPerRun int `yaml:"max-comments-per-run,omitempty" json:"max_comments_per_run,omitempty"`
}
CampaignGovernancePolicy captures lightweight pacing and opt-out policies. This is intentionally scoped to what gh-aw can apply safely and consistently via prompts and safe-output job limits.
type CampaignKPI ¶ added in v0.34.0
type CampaignKPI struct {
// ID is an optional stable identifier for this KPI.
ID string `yaml:"id,omitempty" json:"id,omitempty"`
// Name is a human-readable KPI name.
Name string `yaml:"name" json:"name"`
// Priority indicates whether this KPI is the primary KPI or a supporting KPI.
// Expected values: primary, supporting.
Priority string `yaml:"priority,omitempty" json:"priority,omitempty"`
// Unit is an optional unit string (e.g., percent, days, count).
Unit string `yaml:"unit,omitempty" json:"unit,omitempty"`
// Baseline is the baseline KPI value.
Baseline float64 `yaml:"baseline" json:"baseline"`
// Target is the target KPI value.
Target float64 `yaml:"target" json:"target"`
// TimeWindowDays is the rolling time window (in days) used to compute the KPI.
TimeWindowDays int `yaml:"time-window-days" json:"time-window-days"`
// Direction indicates whether improvement means increasing or decreasing.
// Expected values: increase, decrease.
Direction string `yaml:"direction,omitempty" json:"direction,omitempty"`
// Source describes the signal source used to compute the KPI.
// Expected values: ci, pull_requests, code_security, custom.
Source string `yaml:"source,omitempty" json:"source,omitempty"`
}
CampaignKPI defines a single KPI used for campaign measurement.
type CampaignMetricsSnapshot ¶
type CampaignMetricsSnapshot struct {
Date string `json:"date,omitempty"`
CampaignID string `json:"campaign_id,omitempty"`
TasksTotal int `json:"tasks_total,omitempty"`
TasksCompleted int `json:"tasks_completed,omitempty"`
TasksInProgress int `json:"tasks_in_progress,omitempty"`
TasksBlocked int `json:"tasks_blocked,omitempty"`
VelocityPerDay float64 `json:"velocity_per_day,omitempty"`
EstimatedCompletion string `json:"estimated_completion,omitempty"`
}
CampaignMetricsSnapshot describes the JSON structure used by campaign metrics snapshots written into the memory/campaigns branch.
This mirrors the example in the campaigns guide:
{
"date": "2025-01-16",
"campaign_id": "security-q1-2025",
"tasks_total": 200,
"tasks_completed": 15,
"tasks_in_progress": 30,
"tasks_blocked": 5,
"velocity_per_day": 7.5,
"estimated_completion": "2025-02-12"
}
func FetchMetricsFromRepoMemory ¶
func FetchMetricsFromRepoMemory(metricsGlob string) (*CampaignMetricsSnapshot, error)
FetchMetricsFromRepoMemory attempts to load the latest JSON metrics snapshot matching the provided glob from the memory/campaigns branch. It is best-effort: errors are logged and treated as "no metrics" rather than failing the command.
type CampaignPromptData ¶ added in v0.33.2
type CampaignPromptData struct {
// CampaignID is the unique identifier for this campaign.
CampaignID string
// CampaignName is the human-readable name of this campaign.
CampaignName string
// Objective is the campaign objective statement.
Objective string
// KPIs is the KPI definition list for this campaign.
KPIs []CampaignKPI
// ProjectURL is the GitHub Project URL
ProjectURL string
// CursorGlob is a glob for locating the durable cursor/checkpoint file in repo-memory.
CursorGlob string
// MetricsGlob is a glob for locating the metrics snapshot directory in repo-memory.
MetricsGlob string
// MaxDiscoveryItemsPerRun caps how many candidate items may be scanned during discovery.
MaxDiscoveryItemsPerRun int
// MaxDiscoveryPagesPerRun caps how many pages may be fetched during discovery.
MaxDiscoveryPagesPerRun int
// MaxProjectUpdatesPerRun caps how many project update writes may happen per run.
MaxProjectUpdatesPerRun int
// MaxProjectCommentsPerRun caps how many comments may be written per run.
MaxProjectCommentsPerRun int
// Workflows is the list of worker workflow IDs associated with this campaign.
Workflows []string
}
CampaignPromptData holds data for rendering campaign orchestrator prompts.
type CampaignRuntimeStatus ¶
type CampaignRuntimeStatus struct {
ID string `json:"id" console:"header:ID"`
Name string `json:"name" console:"header:Name"`
Workflows []string `json:"workflows,omitempty" console:"header:Workflows,omitempty"`
Compiled string `json:"compiled" console:"header:Compiled"`
// Optional metrics from repo-memory (when MetricsGlob is set and a
// matching JSON snapshot is found on the memory/campaigns branch).
MetricsTasksTotal int `json:"metrics_tasks_total,omitempty" console:"header:Tasks Total,omitempty"`
MetricsTasksCompleted int `json:"metrics_tasks_completed,omitempty" console:"header:Tasks Completed,omitempty"`
MetricsVelocityPerDay float64 `json:"metrics_velocity_per_day,omitempty" console:"header:Velocity/Day,omitempty"`
MetricsEstimatedCompletion string `json:"metrics_estimated_completion,omitempty" console:"header:ETA,omitempty"`
// Optional durable cursor/checkpoint info from repo-memory.
CursorPath string `json:"cursor_path,omitempty" console:"header:Cursor Path,omitempty,maxlen:40"`
CursorUpdatedAt string `json:"cursor_updated_at,omitempty" console:"header:Cursor Updated,omitempty,maxlen:30"`
}
CampaignRuntimeStatus represents the live status of a campaign, including compiled workflow state and optional metrics/cursor info.
func BuildRuntimeStatus ¶
func BuildRuntimeStatus(spec CampaignSpec, workflowsDir string) CampaignRuntimeStatus
BuildRuntimeStatus builds a CampaignRuntimeStatus for a single campaign spec.
type CampaignSpec ¶
type CampaignSpec struct {
ID string `yaml:"id" json:"id" console:"header:ID"`
Name string `yaml:"name" json:"name" console:"header:Name,maxlen:30"`
Description string `yaml:"description,omitempty" json:"description,omitempty" console:"header:Description,omitempty,maxlen:60"`
// Objective is an optional outcome-owned statement describing what success means
// for this campaign.
Objective string `yaml:"objective,omitempty" json:"objective,omitempty" console:"header:Objective,omitempty,maxlen:60"`
// KPIs is an optional list of KPIs used to measure progress toward the objective.
// Recommended: 1 primary KPI plus up to 2 supporting KPIs.
KPIs []CampaignKPI `yaml:"kpis,omitempty" json:"kpis,omitempty"`
// ProjectURL points to the GitHub Project used as the primary campaign
// dashboard.
ProjectURL string `yaml:"project-url,omitempty" json:"project_url,omitempty" console:"header:Project URL,omitempty,maxlen:40"`
// Version is an optional spec version string (for example: v1).
// When omitted, it defaults to v1 during validation.
Version string `yaml:"version,omitempty" json:"version,omitempty" console:"header:Version,omitempty"`
// Workflows associates this campaign with one or more workflow IDs
// (basename of the Markdown file without .md).
Workflows []string `yaml:"workflows,omitempty" json:"workflows,omitempty" console:"header:Workflows,omitempty,maxlen:40"`
// MemoryPaths documents where this campaign writes its repo-memory
// (for example: memory/campaigns/incident-response/**).
MemoryPaths []string `yaml:"memory-paths,omitempty" json:"memory_paths,omitempty" console:"header:Memory Paths,omitempty,maxlen:40"`
// MetricsGlob is an optional glob (relative to the repository root)
// used to locate JSON metrics snapshots stored in the
// memory/campaigns branch. When set, `gh aw campaign status` will
// attempt to read the latest matching metrics file and surface a few
// key fields.
MetricsGlob string `yaml:"metrics-glob,omitempty" json:"metrics_glob,omitempty" console:"header:Metrics Glob,omitempty,maxlen:30"`
// CursorGlob is an optional glob (relative to the repository root)
// used to locate a durable cursor/checkpoint file stored in the
// memory/campaigns branch. When set, generated coordinator workflows
// will be instructed to continue incremental discovery from this cursor
// and `gh aw campaign status` will surface its freshness.
CursorGlob string `yaml:"cursor-glob,omitempty" json:"cursor_glob,omitempty" console:"header:Cursor Glob,omitempty,maxlen:30"`
// Owners lists the primary human owners for this campaign.
Owners []string `yaml:"owners,omitempty" json:"owners,omitempty" console:"header:Owners,omitempty,maxlen:30"`
// ExecutiveSponsors lists executive stakeholders or sponsors who are
// accountable for the outcome of this campaign.
ExecutiveSponsors []string `` /* 127-byte string literal not displayed */
// RiskLevel is an optional free-form field (e.g. low/medium/high).
RiskLevel string `yaml:"risk-level,omitempty" json:"risk_level,omitempty" console:"header:Risk Level,omitempty"`
// State describes the lifecycle stage of the campaign definition.
// Valid values are: planned, active, paused, completed, archived.
State string `yaml:"state,omitempty" json:"state,omitempty" console:"header:State,omitempty"`
// Tags provide free-form categorization for reporting (for example:
// security, modernization, rollout).
Tags []string `yaml:"tags,omitempty" json:"tags,omitempty" console:"header:Tags,omitempty,maxlen:30"`
// AllowedSafeOutputs documents which safe-outputs operations this
// campaign is expected to use (for example: create-issue,
// create-pull-request). This is currently informational but can be
// enforced by validation in the future.
AllowedSafeOutputs []string `` /* 133-byte string literal not displayed */
// ProjectGitHubToken is an optional GitHub token expression (e.g.,
// ${{ secrets.GH_AW_PROJECT_GITHUB_TOKEN }}) used for GitHub Projects v2
// operations. When specified, this token is passed to the update-project
// safe output configuration in the generated orchestrator workflow.
ProjectGitHubToken string `` /* 126-byte string literal not displayed */
// Governance configures lightweight pacing and opt-out policies for campaign
// orchestrator workflows. These guardrails are primarily enforced through
// generated prompts and safe-output maxima.
Governance *CampaignGovernancePolicy `yaml:"governance,omitempty" json:"governance,omitempty"`
// ApprovalPolicy describes high-level approval expectations for this
// campaign (for example: number of approvals and required roles).
ApprovalPolicy *CampaignApprovalPolicy `yaml:"approval-policy,omitempty" json:"approval-policy,omitempty"`
// ConfigPath is populated at load time with the relative path of
// the YAML file on disk, to help users locate definitions.
ConfigPath string `yaml:"-" json:"config_path" console:"header:Config Path,maxlen:60"`
}
CampaignSpec defines a first-class campaign configuration loaded from YAML frontmatter in Markdown files.
Files are discovered from the local repository under:
.github/workflows/*.campaign.md
This provides a thin, declarative layer on top of existing agentic workflows and repo-memory conventions.
func FilterSpecs ¶
func FilterSpecs(specs []CampaignSpec, pattern string) []CampaignSpec
FilterSpecs filters campaigns by a simple substring match on ID or Name (case-insensitive). When pattern is empty, all campaigns are returned.
func LoadSpecs ¶
func LoadSpecs(rootDir string) ([]CampaignSpec, error)
LoadSpecs scans the repository for campaign spec files and returns a slice of CampaignSpec. Campaign specs are stored as .campaign.md files in .github/workflows/. If the workflows directory does not exist, it returns an empty slice and no error.
func ValidateSpecFromFile ¶
func ValidateSpecFromFile(filePath string) (*CampaignSpec, []string, error)
ValidateSpecFromFile validates a campaign spec file by loading and validating it. This is useful for validation commands that operate on files directly.
type CampaignValidationResult ¶
type CampaignValidationResult struct {
ID string `json:"id" console:"header:ID"`
Name string `json:"name" console:"header:Name"`
ConfigPath string `json:"config_path" console:"header:Config Path"`
Problems []string `json:"problems,omitempty" console:"header:Problems,omitempty"`
}
CampaignValidationResult represents the result of validating a campaign spec.