Documentation
¶
Overview ¶
build_gate_config.go defines Build Gate validation configuration types.
These types configure how Build Gate validation runs before/after mig execution.
build_gate_image_rule.go defines Build Gate image mapping types for stack-based image selection.
These types configure how Build Gate resolves runtime images when Stack Gate is enabled. Image rules map stack expectations (language, release, tool) to container images with specificity-based resolution.
## Resolution Algorithm
The resolver selects images based on specificity:
- Specificity 4: language + tool + release (most specific, highest priority)
- Specificity 3: language + tool
- Specificity 2: language + release
- Specificity 1: language-only (broad fallback)
When multiple rules match, the highest specificity wins. Ties at the same specificity level with different images are configuration errors.
## Related Files
- build_gate_image_rule_parse.go: Parsing from map[string]any
- build_gate_image_rule_wire.go: Wire serialization to map[string]any
- build_gate_image_resolver.go: Runtime resolution implementation
build_gate_image_rule_parse.go provides parsing functions for Build Gate image rules.
These functions parse BuildGateImageRule from map[string]any intermediate representations (from JSON/YAML input).
command_spec.go provides polymorphic command handling for mig specs.
CommandSpec represents container commands that can be specified in two forms:
- Shell string: Executed via /bin/sh -c (e.g., "echo hello && ls -la")
- Exec array: Executed directly without shell wrapper (e.g., ["/bin/sh", "-c", "echo"])
Both forms are first-class citizens of the mig spec schema, enabling:
- Simple commands using a single shell string for convenience.
- Complex commands using exec arrays for precise control over arguments.
The type implements JSON and YAML marshaling/unmarshaling to support both forms transparently in spec files.
hydra.go defines Hydra canonical stored-entry parsers and validators for the envs/in/out/home/tmp contract fields.
Canonical stored-entry formats:
- in: "shortHash:dst" where dst starts with /in/
- out: "shortHash:dst" where dst starts with /out/
- home: "shortHash:dst{:ro}" where dst is $HOME-relative (no leading /)
- tmp: "shortHash:dst" where dst starts with /tmp/
shortHash is a hex-only, colon-free prefix of the full content hash.
Package contracts defines shared workflow types.
migs_spec.go provides the core typed model for Mig run specifications. This eliminates drift between CLI/server/nodeagent spec parsing by providing a single source of truth for spec structure.
## Canonical Spec Shape
The MigSpec type supports a single canonical shape:
- All runs use steps[] (even single-step runs).
- Global build gate policy lives under build_gate.
## Related Files
The Mig spec implementation is split across several files:
- migs_spec.go: Core types (MigSpec, MigStep) and validation
- command_spec.go: Polymorphic command handling (CommandSpec)
- build_gate_config.go: Build gate configuration types
- migs_spec_parse.go: JSON parsing functions
## Usage
Parse specs using ParseMigSpecJSON (in migs_spec_parse.go):
spec, err := contracts.ParseMigSpecJSON(jsonBytes)
if err != nil {
return err // structured validation error
}
// Use typed fields: spec.Steps, spec.BuildGate, etc.
migs_spec_parse.go provides JSON parsing for Mig specifications.
Usage:
spec, err := contracts.ParseMigSpecJSON(jsonBytes)
if err != nil {
return err // structured validation error with field paths
}
YAML files are accepted at the CLI boundary by loading into map[string]any, marshaling to JSON, and validating via ParseMigSpecJSON.
job_image.go provides stack-aware image resolution for mig specs.
This file implements the JobImage type that supports two canonical forms:
- Universal image (string): A single image used for all build stacks.
- Stack-specific image (map): Different images per detected build stack.
Both forms are intentionally supported as first-class citizens of the mig spec schema. The dual-form design enables:
- Simple configurations using a single image string for stack-agnostic migs.
- Optimized configurations using stack-specific images for tools like Maven or Gradle that benefit from dedicated container environments.
## Stack Resolution Rules
When resolving an image for a given stack:
- If JobImage is a string, return that string (universal image).
- If JobImage is a map: a. Prefer an exact stack key match (e.g., "java-maven", "java-gradle"). b. Fall back to "default" when present and no exact match exists. c. Return an error when neither a matching key nor "default" is present.
## Supported Stack Names
The following stack names are recognized for image resolution:
- "java-maven": Maven-based Java projects (pom.xml detected)
- "java-gradle": Gradle-based Java projects (build.gradle detected)
- "java": Generic Java projects (no build tool detected)
- "unknown": No recognized stack markers found
- "default": Fallback key in stack maps
stack_gate_spec.go defines Stack Gate types for explicit stack expectations.
Stack Gate allows mig specs to declare explicit expectations about the repository's technology stack (language, build tool, release version). This enables:
- Validation of contradictory multi-step runs before execution
- Stack-based image selection for mig containers
- Chain validation across step boundaries (outbound → inbound)
## Wire Format
Stack Gate configuration appears in the steps[] array:
steps:
- name: java11-to-17
image: ghcr.io/iw2rmb/ploy/migs-orw:latest
stack:
inbound:
enabled: true
expect: { language: java, tool: maven, release: "11" }
outbound:
enabled: true
expect: { language: java, tool: maven, release: "17" }
stack_gate_spec_parse.go provides parsing functions for Stack Gate configuration.
These functions parse Stack Gate specs from map[string]any intermediate representations (from JSON/YAML input).
Index ¶
- Constants
- Variables
- func ApplyBuildGatePhaseToGateSpec(spec *StepGateSpec, phase *BuildGatePhaseConfig)
- func CopyEnv(env map[string]string) map[string]string
- func ExpandImageTemplate(image string, stack *StackExpectation) (string, error)
- func MarshalJobMeta(m *JobMeta) ([]byte, error)
- func MergeEnv(base, override map[string]string) map[string]string
- func MigSpecSchemaJSON() ([]byte, error)
- func ParseReleaseValue(v any, field string) (string, error)
- func StackFieldsMatch(lang, tool, release, wantLang, wantTool, wantRelease string) bool
- func ValidateHomeDestination(dst string) error
- func ValidateHydraHomeEntries(entries []string, prefix string) error
- func ValidateHydraInEntries(entries []string, prefix string) error
- func ValidateHydraOutEntries(entries []string, prefix string) error
- func ValidateHydraSection(section string) error
- func ValidateHydraTmpEntries(entries []string, prefix string) error
- func ValidateMigSpecJSON(raw []byte) error
- type BuildGateConfig
- type BuildGateImageMapping
- type BuildGateImageRule
- type BuildGateLogFinding
- type BuildGatePhaseConfig
- type BuildGateResourceUsage
- type BuildGateStackConfig
- type BuildGateStackMode
- type BuildGateStageMetadata
- type BuildGateStaticCheckFailure
- type BuildGateStaticCheckReport
- type BuildMeta
- type CommandSpec
- func (c CommandSpec) IsEmpty() bool
- func (c CommandSpec) IsZero() bool
- func (c CommandSpec) MarshalJSON() ([]byte, error)
- func (c CommandSpec) MarshalYAML() (interface{}, error)
- func (c CommandSpec) ToSlice() []string
- func (c *CommandSpec) UnmarshalJSON(data []byte) error
- func (c *CommandSpec) UnmarshalYAML(node *yaml.Node) error
- type GateClaimContext
- type JobImage
- func (m JobImage) IsEmpty() bool
- func (m JobImage) IsStackSpecific() bool
- func (m JobImage) IsUniversal() bool
- func (m JobImage) MarshalJSON() ([]byte, error)
- func (m JobImage) MarshalYAML() (any, error)
- func (m JobImage) ResolveImage(stack MigStack) (string, error)
- func (m JobImage) String() string
- func (m *JobImage) UnmarshalJSON(data []byte) error
- func (m *JobImage) UnmarshalYAML(value *yaml.Node) error
- type JobKind
- type JobMeta
- type ManifestReference
- type MigClaimContext
- type MigSpec
- type MigStack
- type MigStep
- type MigStepOptions
- type ParsedStoredEntry
- type RepoMaterialization
- type StackExpectation
- type StackGatePhaseSpec
- type StackGateResult
- type StackGateSpec
- type StageName
- type StepArtifact
- type StepGateSpec
- type StepGateStackSpec
- type StepInput
- type StepInputArtifactRef
- type StepInputHydration
- type StepInputMode
- type StepManifest
- type StepOutput
- type StepResourceSpec
- type SubjectSet
- type WorkflowRun
Constants ¶
const ( PLOYStackLanguageEnv = "PLOY_STACK_LANGUAGE" PLOYStackToolEnv = "PLOY_STACK_TOOL" PLOYStackReleaseEnv = "PLOY_STACK_RELEASE" )
const SchemaVersion = "2025-09-27.1"
SchemaVersion identifies the JSON envelope version used by workflow run envelopes, checkpoints, and artifact messages. It must be included in all published envelopes so consumers can validate and evolve parsers safely.
Variables ¶
var ValidHydraSections = map[string]bool{ "pre_gate": true, "post_gate": true, "mig": true, }
ValidHydraSections lists the known section names for typed Hydra overlays.
Functions ¶
func ApplyBuildGatePhaseToGateSpec ¶
func ApplyBuildGatePhaseToGateSpec(spec *StepGateSpec, phase *BuildGatePhaseConfig)
ApplyBuildGatePhaseToGateSpec copies the gate execution fields from a BuildGatePhaseConfig into the corresponding fields of a StepGateSpec. StackDetect is set only when phase.Stack has a non-empty mode.
func CopyEnv ¶
CopyEnv returns a shallow copy of the given environment map. Returns nil when the input is empty or nil.
func ExpandImageTemplate ¶
func ExpandImageTemplate(image string, stack *StackExpectation) (string, error)
ExpandImageTemplate expands stack and env placeholders in image templates.
Supported stack placeholders:
- ${stack.language}
- ${stack.release}
- ${stack.tool}
Supported env placeholders:
- $VAR
- ${VAR}
Returns an error when:
- an unknown stack placeholder is used
- a required stack value is unavailable
- an environment variable placeholder is unresolved
func MarshalJobMeta ¶
MarshalJobMeta encodes a JobMeta struct to JSON bytes suitable for storing in jobs.meta JSONB.
Returns an error if m is nil or if the metadata fails validation. Callers must provide a valid JobMeta with a recognized Kind field.
func MergeEnv ¶
MergeEnv returns a new map containing all entries from base with override entries applied on top. Returns nil when both inputs are empty or nil.
func MigSpecSchemaJSON ¶
MigSpecSchemaJSON returns the embedded mig JSON Schema bytes.
func ParseReleaseValue ¶
ParseReleaseValue converts a release value (string, int, or float) to a string. This normalizes map-backed JSON/YAML values so all parser paths share the same release coercion semantics.
func StackFieldsMatch ¶
StackFieldsMatch compares two (language, tool, release) tuples. Language and tool are compared case-insensitively after trimming whitespace. Release is compared after trimming only (case-sensitive). Empty "want" fields are treated as wildcards (always match).
func ValidateHomeDestination ¶
ValidateHomeDestination validates a home destination path without requiring a full canonical entry. The destination must be relative, non-empty, cleaned, and free of path traversal.
func ValidateHydraHomeEntries ¶
ValidateHydraHomeEntries validates a slice of canonical `home` entries.
func ValidateHydraInEntries ¶
ValidateHydraInEntries validates a slice of canonical `in` entries.
func ValidateHydraOutEntries ¶
ValidateHydraOutEntries validates a slice of canonical `out` entries.
func ValidateHydraSection ¶
ValidateHydraSection returns an error if section is not a known Hydra section.
func ValidateHydraTmpEntries ¶
ValidateHydraTmpEntries validates a slice of canonical `tmp` entries.
func ValidateMigSpecJSON ¶
ValidateMigSpecJSON validates raw JSON against the embedded mig JSON Schema.
Types ¶
type BuildGateConfig ¶
type BuildGateConfig struct {
// Disabled skips Build Gate jobs when true.
Disabled bool `json:"disabled,omitempty" yaml:"disabled,omitempty"`
// Pre configures stack detection policy for the pre-gate phase.
Pre *BuildGatePhaseConfig `json:"pre,omitempty" yaml:"pre,omitempty"`
// Post configures stack detection policy for the post-gate phase.
Post *BuildGatePhaseConfig `json:"post,omitempty" yaml:"post,omitempty"`
// Images provides mig-level image mapping overrides for Build Gate image resolution.
// These rules override the default mapping file.
Images []BuildGateImageRule `json:"images,omitempty" yaml:"images,omitempty"`
}
BuildGateConfig configures Build Gate validation for a mig run.
type BuildGateImageMapping ¶
type BuildGateImageMapping struct {
// Images holds the image rules from this source.
Images []BuildGateImageRule
}
BuildGateImageMapping holds rules from a single source for validation. Each precedence level (default file, cluster inline, mig override) has its own mapping that is validated independently before merging.
func (BuildGateImageMapping) Validate ¶
func (m BuildGateImageMapping) Validate(prefix string) error
Validate checks that the mapping is well-formed. Validation rules:
- Each rule must have language (required)
- Each rule must have image (required)
- No duplicate selectors within this mapping
The prefix parameter is used for error messages (e.g., "build_gate.images").
type BuildGateImageRule ¶
type BuildGateImageRule struct {
// Stack holds the stack expectation to match against.
// Language is required. Release and Tool are optional wildcards.
Stack StackExpectation `json:"stack,omitempty" yaml:"stack,omitempty"`
// Image is the container image URL to use when this rule matches.
// Required field.
Image string `json:"image,omitempty" yaml:"image,omitempty"`
}
BuildGateImageRule maps a stack expectation to a Build Gate runtime image. Each rule matches requests where the expectation fields match (or are wildcards).
func (BuildGateImageRule) Matches ¶
func (r BuildGateImageRule) Matches(exp StackExpectation) bool
Matches returns true if this rule matches the given expectation. A rule matches when:
- Language matches exactly (both required)
- Release matches exactly when rule.Release is set
- Tool matches exactly when rule.Tool is set
func (BuildGateImageRule) SelectorKey ¶
func (r BuildGateImageRule) SelectorKey() string
SelectorKey returns a unique key for duplicate detection. Two rules with the same selector key define the same match criteria and should not coexist within the same precedence level.
Format: "language:release:tool" (empty release/tool become "*").
func (BuildGateImageRule) Specificity ¶
func (r BuildGateImageRule) Specificity() int
Specificity returns the matching priority of this rule. Higher values indicate more specific matches:
- 4: language + tool + release
- 3: language + tool
- 2: language + release
- 1: language-only
type BuildGateLogFinding ¶
type BuildGateLogFinding struct {
Code string `json:"code,omitempty"`
Severity string `json:"severity"`
Message string `json:"message"`
Evidence string `json:"evidence,omitempty"`
}
BuildGateLogFinding records a normalized build log finding used for guidance.
func (BuildGateLogFinding) Validate ¶
func (f BuildGateLogFinding) Validate() error
Validate ensures log finding entries include required guidance details.
type BuildGatePhaseConfig ¶
type BuildGatePhaseConfig struct {
// Stack configures stack detection behavior for this gate phase.
Stack *BuildGateStackConfig `json:"stack,omitempty" yaml:"stack,omitempty"`
}
BuildGatePhaseConfig configures a single phase of Build Gate execution. This holds optional stack detection configuration and prep overrides.
type BuildGateResourceUsage ¶
type BuildGateResourceUsage struct {
// Limits configured for the container (0 means unlimited/not set).
LimitNanoCPUs int64 `json:"limit_nano_cpus"`
LimitMemoryBytes int64 `json:"limit_memory_bytes"`
// Observed usage during the container lifetime.
CPUTotalNs uint64 `json:"cpu_total_ns"`
MemUsageBytes uint64 `json:"mem_usage_bytes"`
MemMaxBytes uint64 `json:"mem_max_bytes"`
BlkioReadBytes uint64 `json:"blkio_read_bytes"`
BlkioWriteBytes uint64 `json:"blkio_write_bytes"`
SizeRwBytes *int64 `json:"size_rw_bytes,omitempty"`
}
BuildGateResourceUsage captures container limits and observed usage metrics from the gate execution container.
type BuildGateStackConfig ¶
type BuildGateStackConfig struct {
Mode BuildGateStackMode `json:"mode,omitempty" yaml:"mode,omitempty"`
Language string `json:"language,omitempty" yaml:"language,omitempty"`
Tool string `json:"tool,omitempty" yaml:"tool,omitempty"`
Release string `json:"release,omitempty" yaml:"release,omitempty"`
}
BuildGateStackConfig configures expected stack information for a gate phase.
func (*BuildGateStackConfig) UnmarshalJSON ¶
func (s *BuildGateStackConfig) UnmarshalJSON(data []byte) error
UnmarshalJSON handles numeric release values (e.g., YAML `release: 11` → JSON number).
type BuildGateStackMode ¶
type BuildGateStackMode string
BuildGateStackMode controls how a phase stack config interacts with detection.
const ( BuildGateStackModeForced BuildGateStackMode = "forced" BuildGateStackModeStrict BuildGateStackMode = "strict" BuildGateStackModeFallback BuildGateStackMode = "fallback" )
type BuildGateStageMetadata ¶
type BuildGateStageMetadata struct {
LogDigest types.Sha256Digest `json:"log_digest,omitempty"`
StaticChecks []BuildGateStaticCheckReport `json:"static_checks,omitempty"`
// ExecutedCommand is the exact gate command shell payload executed by the
// gate container.
ExecutedCommand string `json:"executed_command,omitempty"`
// Detected captures the resolved gate stack identity used for this gate
// execution, including optional release matching.
Detected *StackExpectation `json:"detected_stack,omitempty"`
LogFindings []BuildGateLogFinding `json:"log_findings,omitempty"`
// RuntimeImage is the container image name used to run the gate container.
// Not serialized in JSON APIs.
RuntimeImage string `json:"-"`
// StackGate captures the outcome of Stack Gate pre-check validation.
// Present only when Stack Gate mode is enabled.
StackGate *StackGateResult `json:"stack_gate,omitempty"`
// LogsText carries the raw build logs text for node-local processing.
// Not serialized in JSON APIs.
LogsText string `json:"-"`
// Resources summarizes container limits and observed usage for the gate run.
// Not serialized in JSON APIs.
Resources *BuildGateResourceUsage `json:"-"`
// BugSummary is a short one-line description of the gate failure.
// Max 200 chars, no newlines.
BugSummary string `json:"bug_summary,omitempty"`
}
BuildGateStageMetadata captures build gate metadata published with checkpoints.
func (BuildGateStageMetadata) DetectedStack ¶
func (m BuildGateStageMetadata) DetectedStack() MigStack
DetectedStack returns the MigStack derived from the first static check's tool. This provides deterministic stack identification for stack-aware image selection in mig steps.
The detected stack is derived from the Build Gate's tool detection:
- "maven" tool → MigStackJavaMaven
- "gradle" tool → MigStackJavaGradle
- "java" tool → MigStackJava
- unknown/empty → MigStackUnknown
This method ensures the same stack value is visible to mig executions, enabling consistent image resolution.
func (BuildGateStageMetadata) DetectedStackExpectation ¶
func (m BuildGateStageMetadata) DetectedStackExpectation() *StackExpectation
DetectedStackExpectation returns the normalized detected stack expectation. For backward compatibility with older metadata payloads, it falls back to static_checks[0] when detected_stack is absent.
func (BuildGateStageMetadata) Validate ¶
func (m BuildGateStageMetadata) Validate() error
Validate ensures build gate metadata entries are well formed.
type BuildGateStaticCheckFailure ¶
type BuildGateStaticCheckFailure struct {
RuleID string `json:"rule_id,omitempty"`
File string `json:"file,omitempty"`
Line int `json:"line,omitempty"`
Column int `json:"column,omitempty"`
Severity string `json:"severity"`
Message string `json:"message"`
}
BuildGateStaticCheckFailure captures a single diagnostic from a static check tool.
func (BuildGateStaticCheckFailure) Validate ¶
func (f BuildGateStaticCheckFailure) Validate() error
Validate ensures static check failure entries include required details.
type BuildGateStaticCheckReport ¶
type BuildGateStaticCheckReport struct {
Language string `json:"language,omitempty"`
Tool string `json:"tool"`
Passed bool `json:"passed"`
Failures []BuildGateStaticCheckFailure `json:"failures,omitempty"`
}
BuildGateStaticCheckReport summarises an individual static analysis invocation.
func (BuildGateStaticCheckReport) Validate ¶
func (r BuildGateStaticCheckReport) Validate() error
Validate ensures the static check report is well formed.
type BuildMeta ¶
type BuildMeta struct {
// Tool identifies the build tool (e.g., "maven", "gradle", "npm", "bazel").
Tool string `json:"tool,omitempty"`
// Command is the full command line executed (for diagnostics).
Command string `json:"command,omitempty"`
// StatusDetails provides additional context on build outcome.
StatusDetails string `json:"status_details,omitempty"`
// Metrics contains arbitrary build metrics (e.g., compilation time, test count).
Metrics map[string]interface{} `json:"metrics,omitempty"`
}
BuildMeta captures metadata for build tool invocations stored in jobs.meta. This consolidates fields previously tracked in the separate builds table.
type CommandSpec ¶
type CommandSpec struct {
// Shell holds the command when specified as a single shell string.
// When non-empty, the command is executed via ["/bin/sh", "-c", Shell].
Shell string
// Exec holds the command when specified as an exec array.
// When non-nil, the command is executed directly without a shell wrapper.
Exec []string
}
CommandSpec represents a container command as either a shell string or exec array. This type encapsulates the polymorphic command representation in mig specs.
JSON/YAML Examples:
# Shell string form (executed via /bin/sh -c): command: "echo hello && ls -la" # Exec array form (executed directly): command: ["/bin/sh", "-c", "echo hello"]
func ParseCommandSpec ¶
func ParseCommandSpec(v any) (CommandSpec, error)
ParseCommandSpec parses a command value from map-backed JSON/YAML input. Supported forms:
- string: shell command
- []string: exec command
- []any: exec command elements must all be strings
func (CommandSpec) IsEmpty ¶
func (c CommandSpec) IsEmpty() bool
IsEmpty returns true if no command is specified.
func (CommandSpec) IsZero ¶
func (c CommandSpec) IsZero() bool
IsZero lets encoding/json omit empty commands from parent structs.
func (CommandSpec) MarshalJSON ¶
func (c CommandSpec) MarshalJSON() ([]byte, error)
MarshalJSON implements json.Marshaler for CommandSpec. Serializes as a string when Shell is set, or as an array when Exec is set.
func (CommandSpec) MarshalYAML ¶
func (c CommandSpec) MarshalYAML() (interface{}, error)
MarshalYAML implements yaml.Marshaler for CommandSpec.
func (CommandSpec) ToSlice ¶
func (c CommandSpec) ToSlice() []string
ToSlice converts the command to a []string suitable for container execution. Returns nil if the command is empty.
Conversion rules:
- Exec array: returned as-is
- Shell string: wrapped as ["/bin/sh", "-c", Shell]
- Empty: returns nil
func (*CommandSpec) UnmarshalJSON ¶
func (c *CommandSpec) UnmarshalJSON(data []byte) error
UnmarshalJSON implements json.Unmarshaler for CommandSpec. Accepts both string and array forms from JSON.
func (*CommandSpec) UnmarshalYAML ¶
func (c *CommandSpec) UnmarshalYAML(node *yaml.Node) error
UnmarshalYAML implements yaml.Unmarshaler for CommandSpec.
type GateClaimContext ¶
type GateClaimContext struct {
CycleName string `json:"cycle_name"`
}
GateClaimContext carries concrete gate execution routing.
func (*GateClaimContext) Normalize ¶
func (c *GateClaimContext) Normalize()
type JobImage ¶
type JobImage struct {
// Universal holds the image when specified as a single string.
// When non-empty, this image is used regardless of detected stack.
Universal string
// ByStack holds stack-specific images when image is specified as a map.
// Keys are stack names (e.g., "java-maven", "java-gradle", "default").
// When non-nil and non-empty, stack resolution rules apply.
ByStack map[MigStack]string
}
JobImage represents a mig container image specification supporting two canonical forms: universal images (single string) and stack-specific images (map by stack). Both forms are first-class schema options.
YAML/JSON Examples:
# Universal image (string form) — used for all stacks: image: ghcr.io/iw2rmb/ploy/migs-openrewrite:latest # Stack-specific images (map form) — per-stack optimization: image: default: ghcr.io/iw2rmb/ploy/migs-openrewrite:latest java-maven: ghcr.io/iw2rmb/ploy/orw-cli:latest java-gradle: ghcr.io/iw2rmb/ploy/orw-cli:latest
func ParseJobImage ¶
ParseJobImage parses an image specification from an untyped value. Both canonical forms are accepted:
- string: Parsed as a universal image (used for all stacks).
- map[string]any or map[string]string: Parsed as stack-specific images.
Returns an empty JobImage for nil input without error.
func (JobImage) IsStackSpecific ¶
IsStackSpecific returns true if the image is specified as a stack map.
func (JobImage) IsUniversal ¶
IsUniversal returns true if the image is specified as a universal string.
func (JobImage) MarshalJSON ¶
MarshalJSON implements json.Marshaler for JobImage. Serializes as a string when Universal is set, or as a map when ByStack is set.
func (JobImage) MarshalYAML ¶
MarshalYAML implements yaml.Marshaler for JobImage. Serializes as a string when Universal is set, or as a map when ByStack is set.
func (JobImage) ResolveImage ¶
ResolveImage resolves the image for the given stack using resolution rules:
- If JobImage is a universal string, return that string.
- If JobImage is a stack map: a. Prefer an exact stack key match. b. Fall back to "default" when present. c. Return an error when neither exists.
The stack parameter should come from Build Gate detection (e.g., "java-maven"). An empty JobImage returns an error. An empty stack uses "unknown" as default.
func (*JobImage) UnmarshalJSON ¶
UnmarshalJSON implements json.Unmarshaler for JobImage. Accepts both string and map forms from JSON.
type JobKind ¶
type JobKind string
JobKind identifies the execution type for a job in the unified queue. All execution units (migs, gates, builds) are stored in the jobs table with their kind indicated by this field.
const ( // JobKindMig indicates a mig execution job (pre_gate, mig, post_gate). JobKindMig JobKind = "mig" // JobKindGate indicates a build gate validation job. JobKindGate JobKind = "gate" // JobKindBuild indicates a build tool invocation job (maven, gradle, npm, etc.). JobKindBuild JobKind = "build" )
type JobMeta ¶
type JobMeta struct {
// Kind identifies the job type: "mig", "gate", or "build".
Kind JobKind `json:"kind"`
// GateMetadata contains build gate validation metadata when Kind is JobKindGate.
// This includes static check results, log findings, and digest information.
GateMetadata *BuildGateStageMetadata `json:"gate,omitempty"`
// Build contains build tool metadata when Kind is JobKindBuild.
// This includes tool name, command, status details, and metrics.
Build *BuildMeta `json:"build,omitempty"`
// MigStepName stores the user-defined step name from MigSpec.Steps[i].Name
// for mig jobs. Used by the CLI to display a friendly name in --follow mode.
// Only populated for mig jobs (kind="mig") when a step name is provided.
MigStepName string `json:"mig_step_name,omitempty"`
// MigStepIndex stores the concrete mig step index selected for this job.
// Populated for mig jobs so execution does not depend on job name parsing.
MigStepIndex *int `json:"mig_step_index,omitempty"`
// GateCycleName stores the concrete gate cycle name used by gate jobs.
// Examples: pre-gate, post-gate.
GateCycleName string `json:"gate_cycle_name,omitempty"`
}
JobMeta is the structured metadata stored in jobs.meta JSONB. It provides a unified schema for gate, build, and mig metadata, enabling the jobs table to serve as the single execution primitive for all workflow stages.
JSON shape example:
{
"kind": "gate",
"gate": { "log_digest": "...", "static_checks": [...] },
"build": null
}
The kind field is always present and determines which optional metadata section (gate/build) is populated. Mig jobs typically have kind="mig" with no gate or build metadata.
func NewBuildJobMeta ¶
NewBuildJobMeta creates a JobMeta for build tool invocation jobs.
func NewGateJobMeta ¶
func NewGateJobMeta(gate *BuildGateStageMetadata) *JobMeta
NewGateJobMeta creates a JobMeta for gate validation jobs. The gate metadata can be populated later via UpdateGateMeta.
func NewMigJobMeta ¶
func NewMigJobMeta() *JobMeta
NewMigJobMeta creates a JobMeta for mig execution jobs. This is a convenience constructor for the common case of mig jobs that don't carry gate or build metadata.
func NewMigJobMetaWithStepName ¶
NewMigJobMetaWithStepName creates a JobMeta for mig execution jobs with a user-defined step name. The step name is used by the CLI to display a friendly name in --follow mode.
func UnmarshalJobMeta ¶
UnmarshalJobMeta decodes JSON bytes from jobs.meta JSONB into a JobMeta struct.
Returns an error for invalid payloads:
- Empty bytes, empty JSON objects ("{}"), or JSON null are rejected.
- Missing or invalid "kind" field is rejected.
- Payloads that fail JobMeta.Validate() are rejected.
All job metadata must now be structured with an explicit kind field. Use NewMigJobMeta/NewGateJobMeta/NewBuildJobMeta to create valid metadata.
type ManifestReference ¶
ManifestReference identifies a workflow manifest by name and version.
func (ManifestReference) Validate ¶
func (m ManifestReference) Validate() error
Validate requires both name and version to be non‑empty strings.
type MigClaimContext ¶
type MigClaimContext struct {
StepIndex int `json:"step_index"`
}
MigClaimContext carries the concrete mig step selected for execution.
type MigSpec ¶
type MigSpec struct {
// JobID is the claimed job ID injected into the spec at claim time.
JobID types.JobID `json:"job_id,omitempty" yaml:"job_id,omitempty"`
// APIVersion is an optional schema version identifier (e.g., "ploy.mig/v1alpha1").
// Informational only; the control plane forwards specs as opaque JSON.
APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"`
// Name is an optional stable name for publishing and selecting this spec.
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// Description is optional human-readable context for this spec.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
// Steps holds the ordered list of mig steps.
// A spec must contain at least one step.
Steps []MigStep `json:"steps,omitempty" yaml:"steps,omitempty"`
// Envs holds environment variables applied to every step (step envs overrides on conflicts).
Envs map[string]string `json:"envs,omitempty" yaml:"envs,omitempty"`
// BuildGate configures Build Gate validation policy.
// Applies globally to all steps.
BuildGate *BuildGateConfig `json:"build_gate,omitempty" yaml:"build_gate,omitempty"`
// BundleMap maps content hashes used in In/Out/Home/Tmp entries to their
// spec bundle download identifiers (bundle IDs). Populated by the CLI
// compiler during spec submission. The nodeagent uses this to resolve
// shortHash → bundleID for resource download during materialization.
BundleMap map[string]string `json:"bundle_map,omitempty" yaml:"bundle_map,omitempty"`
}
MigSpec is the canonical typed representation of a mig run specification. All specs use steps[]; multi-step runs have len(steps) > 1.
Wire compatibility: This struct marshals to/from JSON with stable field names that match the existing spec schema. The JSON tags are the source of truth for wire format compatibility.
Validation: Use Validate() to check structural correctness after parsing. ParseMigSpecJSON calls Validate() automatically and returns structured errors for invalid input.
func ParseMigSpecJSON ¶
ParseMigSpecJSON parses a mig specification from JSON bytes. Returns a validated MigSpec or an error for invalid/malformed input.
type MigStack ¶
type MigStack string
MigStack represents a detected build stack for image resolution.
const ( // MigStackJavaMaven indicates a Maven-based Java project (pom.xml present). MigStackJavaMaven MigStack = "java-maven" // MigStackJavaGradle indicates a Gradle-based Java project (build.gradle present). MigStackJavaGradle MigStack = "java-gradle" // MigStackJava indicates a generic Java project (no specific build tool). MigStackJava MigStack = "java" // MigStackUnknown indicates no recognized stack markers were found. MigStackUnknown MigStack = "unknown" // MigStackDefault is the fallback key used in stack-specific image maps. MigStackDefault MigStack = "default" )
func ToolToMigStack ¶
ToolToMigStack converts a Build Gate tool name to a MigStack constant. Tool names come from BuildGateStaticCheckReport.Tool after gate execution.
Conversion rules:
- "maven" → MigStackJavaMaven
- "gradle" → MigStackJavaGradle
- "java" → MigStackJava
- "" or unknown → MigStackUnknown
This function enables deterministic stack-aware image selection after Build Gate detection, ensuring mig steps use the correct stack-specific images based on the workspace's detected build system.
type MigStep ¶
type MigStep struct {
// Name is an optional human-readable name for this step.
Name string `json:"name,omitempty" yaml:"name,omitempty"`
// Image is the container image for this step (required).
// Supports both universal images (string) and stack-specific images (map).
Image JobImage `json:"image,omitempty" yaml:"image,omitempty"`
// Command is the container command override for this step (optional).
// Can be a shell string or an exec array.
Command CommandSpec `json:"command,omitempty,omitzero" yaml:"command,omitempty"`
// Envs holds environment variables specific to this step.
Envs map[string]string `json:"envs,omitempty" yaml:"envs,omitempty"`
// Options holds strict, step-scoped runtime options.
Options MigStepOptions `json:"options,omitempty,omitzero" yaml:"options,omitempty"`
// In lists canonical read-only input entries ("shortHash:/in/dst").
In []string `json:"in,omitempty" yaml:"in,omitempty"`
// Out lists canonical read-write output entries ("shortHash:/out/dst").
Out []string `json:"out,omitempty" yaml:"out,omitempty"`
// Home lists canonical home-relative entries ("shortHash:dst{:ro}").
Home []string `json:"home,omitempty" yaml:"home,omitempty"`
// Tmp lists canonical writable temporary entries ("shortHash:/tmp/dst").
Tmp []string `json:"tmp,omitempty" yaml:"tmp,omitempty"`
// Stack configures Stack Gate validation for this step.
// Inbound validates pre-mig expectations; Outbound validates post-mig expectations.
Stack *StackGateSpec `json:"stack,omitempty" yaml:"stack,omitempty"`
}
MigStep describes a single mig step in a run (steps[] array). Each step has its own image, command, and environment configuration. Steps execute sequentially with shared workspace, each running gate+mig.
type MigStepOptions ¶
type MigStepOptions struct {
MountDockerSocket bool `json:"mount_docker_socket,omitempty" yaml:"mount_docker_socket,omitempty"`
}
MigStepOptions describes strict runtime options accepted under steps[].options.
func (MigStepOptions) IsZero ¶
func (o MigStepOptions) IsZero() bool
type ParsedStoredEntry ¶
ParsedStoredEntry holds the result of parsing a canonical stored entry.
func ParseStoredHomeEntry ¶
func ParseStoredHomeEntry(s string) (ParsedStoredEntry, error)
ParseStoredHomeEntry parses a canonical `home` entry: "shortHash:dst{:ro}". dst must be relative (no leading /) and must not traverse above $HOME. Mode defaults to rw; optional :ro suffix forces read-only.
func ParseStoredInEntry ¶
func ParseStoredInEntry(s string) (ParsedStoredEntry, error)
ParseStoredInEntry parses a canonical `in` entry: "shortHash:dst". dst must be absolute and start with "/in/".
func ParseStoredOutEntry ¶
func ParseStoredOutEntry(s string) (ParsedStoredEntry, error)
ParseStoredOutEntry parses a canonical `out` entry: "shortHash:dst". dst must be absolute and start with "/out/".
func ParseStoredTmpEntry ¶
func ParseStoredTmpEntry(s string) (ParsedStoredEntry, error)
ParseStoredTmpEntry parses a canonical `tmp` entry: "shortHash:dst". dst must be absolute and start with "/tmp/".
func (ParsedStoredEntry) CanonicalHomeEntry ¶
func (p ParsedStoredEntry) CanonicalHomeEntry() string
CanonicalHomeEntry reconstructs the canonical stored home entry string from parsed fields: "hash:dst" or "hash:dst:ro".
type RepoMaterialization ¶
type RepoMaterialization struct {
URL types.RepoURL `json:"url,omitempty"`
BaseRef types.GitRef `json:"base_ref,omitempty"`
Commit types.CommitSHA `json:"commit,omitempty"`
WorkspaceHint string `json:"workspace_hint,omitempty"`
}
RepoMaterialization describes repository inputs required for a workflow run.
func (RepoMaterialization) Validate ¶
func (r RepoMaterialization) Validate() error
Validate ensures repo metadata is well formed when provided.
type StackExpectation ¶
type StackExpectation struct {
// Language is the expected programming language (e.g., "java", "go", "python").
Language string `json:"language,omitempty" yaml:"language,omitempty"`
// Tool is the expected build tool (e.g., "maven", "gradle", "npm").
Tool string `json:"tool,omitempty" yaml:"tool,omitempty"`
// Release is the expected version/release (e.g., "11", "17", "3.9").
// Stored as string to handle both integer and string release values in YAML.
Release string `json:"release,omitempty" yaml:"release,omitempty"`
}
StackExpectation describes expected stack characteristics. All fields are optional; omitted fields indicate "any" for that dimension.
func NormalizeStackExpectation ¶
func NormalizeStackExpectation(expect *StackExpectation) *StackExpectation
NormalizeStackExpectation returns a trimmed copy of expect. Nil or fully-empty values normalize to nil.
func (StackExpectation) Equal ¶
func (e StackExpectation) Equal(other StackExpectation) bool
Equal returns true if both expectations have identical field values.
func (StackExpectation) IsEmpty ¶
func (e StackExpectation) IsEmpty() bool
IsEmpty returns true if no expectation fields are set.
func (*StackExpectation) UnmarshalJSON ¶
func (e *StackExpectation) UnmarshalJSON(data []byte) error
UnmarshalJSON handles numeric release values (e.g., YAML `release: 11` → JSON number).
type StackGatePhaseSpec ¶
type StackGatePhaseSpec struct {
// Enabled controls whether this phase is active.
// When false, the phase is skipped entirely.
Enabled bool `json:"enabled,omitempty" yaml:"enabled,omitempty"`
// Expect defines the stack expectations for this phase.
// Only validated when Enabled is true.
Expect *StackExpectation `json:"expect,omitempty" yaml:"expect,omitempty"`
}
StackGatePhaseSpec configures a single phase (inbound or outbound) of Stack Gate.
func (StackGatePhaseSpec) Equal ¶
func (p StackGatePhaseSpec) Equal(other StackGatePhaseSpec) bool
Equal returns true if both phase specs have identical configuration.
func (StackGatePhaseSpec) IsEmpty ¶
func (p StackGatePhaseSpec) IsEmpty() bool
IsEmpty returns true if the phase spec has default values (disabled, no expect).
type StackGateResult ¶
type StackGateResult struct {
Enabled bool `json:"enabled"`
Expected *StackExpectation `json:"expected,omitempty"`
Detected *StackExpectation `json:"detected,omitempty"`
RuntimeImage string `json:"runtime_image,omitempty"`
Result string `json:"result,omitempty"` // "pass", "mismatch", "unknown"
Reason string `json:"reason,omitempty"`
}
StackGateResult captures the outcome of Stack Gate pre-check validation.
func (StackGateResult) Validate ¶
func (r StackGateResult) Validate() error
Validate ensures stack gate result is well formed.
type StackGateSpec ¶
type StackGateSpec struct {
// Inbound configures pre-mig stack validation.
// Validates that the repository matches expectations before the mig runs.
Inbound *StackGatePhaseSpec `json:"inbound,omitempty" yaml:"inbound,omitempty"`
// Outbound configures post-mig stack validation.
// Validates that the mig produced the expected stack transformation.
Outbound *StackGatePhaseSpec `json:"outbound,omitempty" yaml:"outbound,omitempty"`
}
StackGateSpec configures Stack Gate for a mig step. Inbound validates pre-mig expectations; Outbound validates post-mig expectations.
func (StackGateSpec) Equal ¶
func (s StackGateSpec) Equal(other StackGateSpec) bool
Equal returns true if both stack gate specs have identical configuration.
func (StackGateSpec) IsEmpty ¶
func (s StackGateSpec) IsEmpty() bool
IsEmpty returns true if no stack gate configuration is present.
func (StackGateSpec) MarshalJSON ¶
func (s StackGateSpec) MarshalJSON() ([]byte, error)
MarshalJSON returns nil for empty StackGateSpec so that parent structs with omitempty will omit the field entirely.
type StageName ¶
type StageName string
StageName identifies a workflow stage by name.
It is a distinct type to prevent mixing arbitrary strings with stage identifiers in contracts while preserving JSON compatibility (marshals as a plain string).
type StepArtifact ¶
StepArtifact describes an artifact emitted after execution.
type StepGateSpec ¶
type StepGateSpec struct {
Enabled bool
Env map[string]string
// ImageOverrides holds mig-level image mapping overrides for gate execution.
// These rules override the default mapping file.
ImageOverrides []BuildGateImageRule
// StackDetect configures stack detection behavior for this gate.
// mode=forced skips detection and uses the configured stack.
// mode=strict requires detection to match the configured stack.
// mode=fallback uses detection when complete, otherwise the configured stack.
StackDetect *BuildGateStackConfig
// RepoURL is the Git repository URL for remote gate execution.
// Populated from StartRunRequest.RepoURL when building manifests.
RepoURL types.RepoURL
// RepoID is the repo identifier for this execution.
// Used for gate job/runtime correlation.
RepoID types.MigRepoID
// Ref is the Git reference (commit SHA, branch, or tag) for remote gate execution.
// Derived from CommitSHA > BaseRef precedence when building manifests.
Ref types.GitRef
// DiffPatch is an optional gzipped unified diff (base64-encoded) to apply
// on top of the cloned repo_url+ref baseline, avoiding full archive uploads.
// The diff captures all changes relative to the initial repo_url+ref clone.
DiffPatch []byte
// StackGate holds the Stack Gate configuration for this step.
// Used for pre/post gate validation of stack expectations.
StackGate *StepGateStackSpec
}
StepGateSpec configures Build Gate validation post step execution.
The RepoURL and Ref fields provide repo metadata for HTTP-based gate execution, enabling remote Build Gate workers to clone and validate the repository without requiring direct workspace access. These fields are populated from the run's StartRunRequest and threaded through manifests.
Ref precedence (set by manifest builders):
- CommitSHA — pinned commit when available (ensures deterministic validation).
- BaseRef — fallback for baseline validations.
type StepGateStackSpec ¶
type StepGateStackSpec struct {
// Enabled controls whether Stack Gate validation is active for this phase.
Enabled bool
// Expect holds the stack expectations to validate.
// Only validated when Enabled is true.
Expect *StackExpectation
}
StepGateStackSpec holds the effective Stack Gate configuration for a gate phase. This is threaded into manifests from the step's StackGateSpec.
type StepInput ¶
type StepInput struct {
Name string
MountPath string
Mode StepInputMode
SnapshotCID types.CID
DiffCID types.CID
Hydration *StepInputHydration
}
StepInput describes repository state presented to the container.
type StepInputArtifactRef ¶
type StepInputArtifactRef struct {
CID types.CID `json:"cid"`
Digest types.Sha256Digest `json:"digest,omitempty"`
Size int64 `json:"size,omitempty"`
}
StepInputArtifactRef references a snapshot or diff artifact.
type StepInputHydration ¶
type StepInputHydration struct {
BaseSnapshot StepInputArtifactRef `json:"base_snapshot,omitempty"`
Diffs []StepInputArtifactRef `json:"diffs,omitempty"`
Repo *RepoMaterialization `json:"repo,omitempty"`
}
StepInputHydration describes how to materialise repository state for an input.
type StepInputMode ¶
type StepInputMode string
StepInputMode describes how the input is mounted into the container.
const ( // StepInputModeReadOnly mounts the input read-only. StepInputModeReadOnly StepInputMode = "ro" // StepInputModeReadWrite mounts the input read-write. StepInputModeReadWrite StepInputMode = "rw" )
type StepManifest ¶
type StepManifest struct {
ID types.StepID
Name string
Image string
Command []string
Args []string
WorkingDir string
Envs map[string]string
Inputs []StepInput
Outputs []StepOutput
Artifacts []StepArtifact
Gate *StepGateSpec
Resources StepResourceSpec
// Options holds arbitrary run-specific options.
// Read options via OptionString/OptionBool helpers to avoid scattered type
// assertions in callers. This field is not validated and values are never
// logged.
Options map[string]any
// In lists canonical read-only input entries ("shortHash:/in/dst").
In []string
// Out lists canonical read-write output entries ("shortHash:/out/dst").
Out []string
// Home lists canonical home-relative entries ("shortHash:dst{:ro}").
Home []string
// Tmp lists canonical writable temporary entries ("shortHash:/tmp/dst").
Tmp []string
// BundleMap maps content hashes to spec bundle download identifiers.
// The nodeagent uses this to resolve Hydra entry hashes → bundleIDs
// for resource download during staged materialization.
BundleMap map[string]string
}
StepManifest defines the execution contract for a single Mig step.
func (StepManifest) OptionBool ¶
func (m StepManifest) OptionBool(key string) (bool, bool)
OptionBool returns the option value for key when it is of type bool. It returns the bool and true on exact type match; otherwise it returns false and false. The lookup is safe on a zero-value manifest or when Options is nil.
func (StepManifest) OptionString ¶
func (m StepManifest) OptionString(key string) (string, bool)
OptionString returns the option value for key when it is of type string. It returns the string and true on exact type match; otherwise it returns an empty string and false. The lookup is safe on a zero-value manifest or when Options is nil.
func (StepManifest) Validate ¶
func (m StepManifest) Validate() error
Validate ensures the manifest is well-formed.
type StepOutput ¶
StepOutput describes expected paths produced by the container.
type StepResourceSpec ¶
StepResourceSpec captures runtime resource hints.
func (StepResourceSpec) ToLimits ¶
func (s StepResourceSpec) ToLimits() (nanoCPUs int64, memoryBytes int64, diskBytes int64, storageSizeOpt string)
ToLimits converts the resource hints into concrete container limit values.
Returns Docker‑compatible quantities:
- nanoCPUs: 1e9 per CPU (millis → nanos via CPUmilli.DockerNanoCPUs).
- memoryBytes: raw bytes for memory limit (0 means unlimited).
- diskBytes: raw bytes for writable layer limit (best‑effort; 0 means unlimited).
- storageSizeOpt: string form for Docker storage option "size" when supported by the storage driver (empty when unlimited).
type SubjectSet ¶
SubjectSet contains the per‑run subjects used for publishing workflow events. Empty strings are returned when the run ID is blank to signal that publishing should be skipped by callers.
func SubjectsForRun ¶
func SubjectsForRun(runID types.RunID) SubjectSet
SubjectsForRun derives the subjects used to publish checkpoints, artifacts, and status events for a given run ID. When the provided run ID is empty or whitespace, all fields in the returned set are empty.
type WorkflowRun ¶
type WorkflowRun struct {
SchemaVersion string `json:"schema_version"`
RunID types.RunID `json:"run_id"`
Manifest ManifestReference `json:"manifest"`
Repo RepoMaterialization `json:"repo,omitempty"`
}
WorkflowRun is the envelope used when submitting or claiming a workflow run. It carries the schema version, the opaque run identifier, the manifest reference (name/version), and optional repository materialization details for nodes to hydrate workspaces.
func (WorkflowRun) Validate ¶
func (r WorkflowRun) Validate() error
Validate checks that required fields are present and that embedded structures are valid. It requires a non‑empty schema version and run ID, a valid `Manifest`, and (when provided) a valid `Repo`.
Source Files
¶
- build_gate_config.go
- build_gate_image_rule.go
- build_gate_image_rule_parse.go
- build_gate_metadata.go
- claim_execution_context.go
- command_spec.go
- contracts.go
- envutil.go
- hydra.go
- image_template.go
- job_meta.go
- manifest_options.go
- manifest_reference.go
- mig_schema.go
- migs_spec.go
- migs_spec_parse.go
- mod_image.go
- stack_env.go
- stack_gate_spec.go
- stack_gate_spec_parse.go
- stack_match.go
- step_manifest.go
- value_parse.go
- workflow_ticket.go