Documentation
¶
Overview ¶
Package runtask implements the repository task-run lifecycle that ADR-0055 moves from ce-agent-kit into gz-git: run identity, owner, lock, and receipt state live here, and task-manager consumes them through the JSON surface.
The behavioral reference is the parity fixture suite in tests/parity/ — golden files there are machine-captured from the autonomous CE binary (master f927ae5d). When this implementation and the fixtures disagree, the fixtures win; docs/design/RUN_LIFECYCLE_PARITY_CONTRACT.md describes the same surface at the source level.
Index ¶
- Constants
- func IsTerminalExecutionStatus(status string) bool
- func NewEngine() integrateEngine
- func SetRuntimeRevision(v string)
- func SetRuntimeVersion(v string)
- type CommandDiagnostics
- type CommandRequest
- type CommandResult
- type CommandRunner
- type DerivedTaskState
- type Executor
- type ImportCEReport
- type IntegrationNetworkPolicy
- type IntegrationProviderDiagnostics
- type Service
- func (s *Service) Abort(ctx context.Context, task, reason string) (resp TaskResponse, code int)
- func (s *Service) Discard(ctx context.Context, task, reason, takeOverFrom string) (resp TaskResponse, code int)
- func (s *Service) Doctor(ctx context.Context) TaskResponse
- func (s *Service) Finish(ctx context.Context, task string) (resp TaskResponse, code int)
- func (s *Service) ImportCE(ctx context.Context, dryRun bool) (ImportCEReport, error)
- func (s *Service) List(ctx context.Context) TaskResponse
- func (s *Service) Recover(ctx context.Context, task string) (resp TaskResponse, code int)
- func (s *Service) Start(ctx context.Context, task string, kind TaskExecutionType) TaskResponse
- func (s *Service) Status(ctx context.Context, task string) TaskResponse
- type StringList
- type TaskExecution
- type TaskExecutionType
- type TaskLockInfo
- type TaskOwner
- type TaskReceipt
- type TaskResponse
- type TaskRuntimeConfig
Constants ¶
const ( // TaskRuntimeConfigFile holds this checkout's runtime identity -- // repository-id, worktree-roots, integration-provider. Those keys name // machine-local absolute paths, which is why the repository's .gitignore // should exclude it. TaskRuntimeConfigFile = ".gz-git-task.yaml" // RuntimeStateDir names the directory the run lifecycle keeps its state // in, rooted at the git common dir: `<git-common-dir>/gz-git/`. The // common dir is shared by a repository and every linked worktree and is // never part of any working tree, so state written there outlives a // reclaimed worktree without leaving a path that could recreate one. RuntimeStateDir = "gz-git" )
const ( TaskExecutionStatusActive = "ACTIVE" TaskExecutionStatusReady = "READY" TaskExecutionStatusAborted = "ABORTED" TaskExecutionStatusBlocked = "BLOCKED" TaskExecutionStatusDone = "DONE" TaskExecutionStatusUnknown = "UNKNOWN" )
Task execution status tokens as they appear in response documents and receipt records.
Variables ¶
This section is empty.
Functions ¶
func IsTerminalExecutionStatus ¶
IsTerminalExecutionStatus reports whether a record has reached an end state -- one that no further verb can move. DONE and ABORTED are terminal; ACTIVE is running, and BLOCKED and UNKNOWN are awaiting a decision, which is why both still advertise `run-abort`. READY is not an execution status: it is the list-level answer when the runtime responded and nothing is blocked, so this predicate does not treat it as terminal or live.
func NewEngine ¶
func NewEngine() integrateEngine
NewEngine returns the in-process integration engine for this binary.
func SetRuntimeRevision ¶
func SetRuntimeRevision(v string)
SetRuntimeRevision records the build commit for receipt evidence. An unstamped build says unknown rather than inventing an identifier.
func SetRuntimeVersion ¶
func SetRuntimeVersion(v string)
SetRuntimeVersion records the build version for lifecycle reporting.
Types ¶
type CommandDiagnostics ¶
type CommandDiagnostics struct {
Command string `json:"command,omitempty"`
Executable string `json:"executable,omitempty"`
Args []string `json:"args,omitempty"`
Cwd string `json:"cwd,omitempty"`
ExitCode int `json:"exitCode"`
Stdout string `json:"stdout,omitempty"`
Stderr string `json:"stderr,omitempty"`
Error string `json:"error,omitempty"`
NotStarted bool `json:"notStarted,omitempty"`
}
CommandDiagnostics records one executed or not-started command's evidence for receipt diagnostics.
type CommandRequest ¶
CommandRequest names one external command: the tool, its fixed argv, the working directory, and extra environment entries.
type CommandResult ¶
type CommandResult struct {
Stdout string
Stderr string
ExitCode int
Command string
Executable string
Args []string
WorkDir string
Error string
NotStarted bool
}
CommandResult carries output and exit state for one command execution, including the evidence fields receipts record when the command never ran.
type CommandRunner ¶
type CommandRunner interface {
Run(context.Context, CommandRequest) (CommandResult, error)
}
CommandRunner executes an external command and captures stdout/stderr separately.
type DerivedTaskState ¶
type DerivedTaskState struct {
Execution TaskExecution `json:"execution"`
Status string `json:"status"`
AllowedActions []string `json:"allowedActions"`
Reason string `json:"reason"`
NextAction string `json:"nextAction"`
FinishReady bool `json:"finishReady"`
Diagnostics []CommandDiagnostics `json:"diagnostics,omitempty"`
}
DerivedTaskState pairs one recorded execution with the status derived from live repository and receipt evidence.
type Executor ¶
type Executor struct{}
Executor is the production command runner. Only fixed-argv invocations of audited tools (git, wt) go through it; user input never reaches a shell.
func (*Executor) Run ¶
func (e *Executor) Run(ctx context.Context, req CommandRequest) (CommandResult, error)
Run executes req with a resolved absolute executable path and separated output capture, mapping cancellation and lookup failures onto the recorded exit codes (125 canceled, 127 not started).
type ImportCEReport ¶
type ImportCEReport struct {
SchemaVersion int `json:"schemaVersion"`
Imported bool `json:"imported"`
DryRun bool `json:"dryRun,omitempty"`
Executions int `json:"executions"`
Receipts int `json:"receipts"`
SourceDir string `json:"sourceDir"`
TargetDir string `json:"targetDir"`
}
ImportCEReport is the answer of the explicit one-shot import.
type IntegrationNetworkPolicy ¶
type IntegrationNetworkPolicy string
IntegrationNetworkPolicy limits network use by the declared integration provider. An omitted value preserves the existing provider-controlled mode.
const ( IntegrationNetworkPolicyAllow IntegrationNetworkPolicy = "allow" IntegrationNetworkPolicyNoFetch IntegrationNetworkPolicy = "no-fetch" )
Integration network policy values accepted by the runtime declaration.
type IntegrationProviderDiagnostics ¶
type IntegrationProviderDiagnostics struct {
Name string `json:"name"`
Present bool `json:"present"`
Version string `json:"version,omitempty"`
Executable string `json:"executable,omitempty"`
Capabilities map[string]bool `json:"capabilities"`
}
IntegrationProviderDiagnostics records the read-only contract probe for the integration engine selected by the repository. When the engine is this binary the probe reports capabilities from in-process knowledge; the executable and version still name this build.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service carries one repository root and its collaborators for the run lifecycle verbs. It holds no per-run state: all durable state lives in the store under the git common dir.
func NewService ¶
func NewService(root string, runner CommandRunner, engine integrateEngine) *Service
NewService builds a Service for root, using runner for external commands and engine for the in-process integration boundary.
func (*Service) Abort ¶
Abort closes one execution as ABORTED by appending a terminal receipt.
Without it BLOCKED is an absorbing state. A record whose worktree and branch were reclaimed outside gz-git -- by `gz-git integrate`, which is allowed to do exactly that -- derives BLOCKED forever, and listResponse rolls a single blocked record up into a repository-wide failure, so run list and run status exit 1 for as long as it exists.
Evidence is appended, never rewritten. The execution stays in executions.json and receipts.jsonl only grows -- the same shape Finish uses to record a DONE outcome -- so aborting closes the derived state without erasing what happened. Abort touches no worktree, branch, or remote ref: a surviving worktree is reported as a warning for its owner to reclaim deliberately.
func (*Service) Discard ¶
func (s *Service) Discard(ctx context.Context, task, reason, takeOverFrom string) (resp TaskResponse, code int)
Discard removes the exact clean worktree recorded for an unintegrated task. It deliberately uses Worktrunk, and writes an intent receipt before asking Worktrunk to mutate anything, so an interrupted reclaim remains auditable and can be retried from the recorded identity.
func (*Service) Doctor ¶
func (s *Service) Doctor(ctx context.Context) TaskResponse
Doctor answers whether the task runtime dependencies of this checkout are ready, without acquiring the mutation lock: configuration, integration provider presence and capabilities, lock, and receipt readability.
func (*Service) Finish ¶
Finish integrates a clean, fully pushed task branch into its configured source branch and reclaims the worktree, local branch, and remote branch in the same step, answering DONE only from receipt evidence that proves all three.
func (*Service) ImportCE ¶
ImportCE copies in-flight CE task-runtime records into this runtime's state directory, byte for byte. Executions and receipts are evidence: they carry CE's tool stamps and CE's words, and rewriting them would falsify what happened; deriveState reconciles their worktrees and branches against the live repository the same way it reconciles any reclaimed run.
It refuses to merge: gz-git state that already exists is an operator decision, not an import. It refuses to invent: a source with neither executions nor receipts has nothing to carry over. Records are parsed before they are copied, so a corrupt CE file stops here instead of surfacing later as an unreadable state.
func (*Service) List ¶
func (s *Service) List(ctx context.Context) TaskResponse
List answers the repository-shared execution inventory without acquiring the mutation lock: every live execution keeps its own derived state, and terminal ones fold into the aggregate counts.
func (*Service) Recover ¶
Recover closes the narrow exit-3 outcome from run finish. It never invokes the integration engine and never removes a worktree or a ref: it only verifies that the recorded task commit is in the pushed source branch, then appends evidence naming whatever engine cleanup left behind.
func (*Service) Start ¶
func (s *Service) Start(ctx context.Context, task string, kind TaskExecutionType) TaskResponse
Start creates the owner-bound task worktree through Worktrunk and records the ACTIVE execution, returning an existing live execution instead of starting twice and replacing a closed record in place.
type StringList ¶
type StringList []string
StringList accepts either a scalar or a sequence.
The documented shape is a sequence, but a hand-written `integrationBranch: master` parses as a scalar and would otherwise fail the whole file — turning a repository that has declared its target into one reported as having declared nothing, which is the opposite of the truth.
func (StringList) First ¶
func (l StringList) First() string
First returns the first non-empty entry, or "" when the field declares nothing.
Several entries take the first rather than being refused, because that is the answer the worktree audit has always given for this field and a second answer here would put the disagreement back. An empty string is a declaration of nothing, not a declaration of "": a branch with no name resolves to no ref, and failing later with an unresolvable name hides which of the two happened.
func (*StringList) UnmarshalYAML ¶
func (l *StringList) UnmarshalYAML(value *yaml.Node) error
UnmarshalYAML implements the scalar-or-sequence tolerance. A mapping is not a shape this field has; it reads as no declaration rather than failing the whole file, because the other keys in it are still true.
type TaskExecution ¶
type TaskExecution struct {
Task string `json:"task"`
Type TaskExecutionType `json:"type"`
Source string `json:"source"`
Owner TaskOwner `json:"owner"`
Branch string `json:"branch"`
Worktree string `json:"worktree"`
StartedAt time.Time `json:"startedAt"`
UpdatedAt time.Time `json:"updatedAt"`
}
TaskExecution is the current execution identity from metadata.
type TaskExecutionType ¶
type TaskExecutionType string
TaskExecutionType classifies a task run session.
const ( TaskExecutionTypeFeat TaskExecutionType = "feat" TaskExecutionTypeFix TaskExecutionType = "fix" TaskExecutionTypeRefactor TaskExecutionType = "refactor" TaskExecutionTypeDocs TaskExecutionType = "docs" TaskExecutionTypeTest TaskExecutionType = "test" TaskExecutionTypeChore TaskExecutionType = "chore" TaskExecutionTypePerf TaskExecutionType = "perf" )
Task execution types, matching the commit type the task branch name and its worktree directory were created with.
func (TaskExecutionType) Valid ¶
func (t TaskExecutionType) Valid() bool
Valid reports whether t is one of the declared execution types.
type TaskLockInfo ¶
type TaskLockInfo struct {
Path string `json:"path"`
PID int `json:"pid,omitempty"`
CreatedAt time.Time `json:"createdAt,omitempty"`
AgeSeconds int64 `json:"ageSeconds,omitempty"`
PIDRunning *bool `json:"pidRunning,omitempty"`
}
TaskLockInfo describes the mutation lock file for diagnostics: where it lives, who holds it, and whether that holder is still running.
type TaskOwner ¶
type TaskOwner struct {
Actor string `json:"actor"`
Host string `json:"host"`
Kind string `json:"kind"`
}
TaskOwner expresses who controls one execution.
type TaskReceipt ¶
type TaskReceipt struct {
Task string `json:"task"`
Operation string `json:"operation"`
Status string `json:"status"`
Owner TaskOwner `json:"owner"`
PerformedBy *TaskOwner `json:"performedBy,omitempty"`
Branch string `json:"branch"`
Worktree string `json:"worktree"`
Reason string `json:"reason,omitempty"`
CreatedAt time.Time `json:"createdAt"`
SourceHead string `json:"sourceHead,omitempty"`
SourceHeadBefore string `json:"sourceHeadBefore,omitempty"`
BaseHead string `json:"baseHead,omitempty"`
TaskHead string `json:"taskHead,omitempty"`
SourcePushed bool `json:"sourcePushed"`
WorktreeRemoved bool `json:"worktreeRemoved"`
LocalBranchRemoved bool `json:"localBranchRemoved"`
RemoteBranchRemoved bool `json:"remoteBranchRemoved"`
ToolVersion string `json:"tool_version,omitempty"`
ToolRevision string `json:"tool_revision,omitempty"`
Diagnostics []CommandDiagnostics `json:"diagnostics,omitempty"`
}
TaskReceipt is the durable evidence one lifecycle operation wrote: the decision it made, the Git heads it observed, and the recovery state it proved before answering DONE.
type TaskResponse ¶
type TaskResponse struct {
SchemaVersion int `json:"schemaVersion"`
Status string `json:"status"`
ActiveCount int `json:"activeCount"`
Task string `json:"task"`
AllowedActions []string `json:"allowedActions"`
Reason string `json:"reason"`
NextAction string `json:"nextAction"`
FinishReady bool `json:"finishReady"`
Warnings []string `json:"warnings,omitempty"`
Lock *TaskLockInfo `json:"lock,omitempty"`
Execution *TaskExecution `json:"execution,omitempty"`
Executions []TaskExecution `json:"executions,omitempty"`
States []DerivedTaskState `json:"states,omitempty"`
Receipt *TaskReceipt `json:"receipt,omitempty"`
Diagnostics []CommandDiagnostics `json:"diagnostics,omitempty"`
Provider *IntegrationProviderDiagnostics `json:"provider,omitempty"`
}
TaskResponse is the single response document every verb prints with --json; task-manager parses only this shape.
type TaskRuntimeConfig ¶
type TaskRuntimeConfig struct {
SchemaVersion int `yaml:"schema-version,omitempty" json:"schemaVersion"`
RepositoryID string `yaml:"repository-id" json:"repositoryId"`
WorktreeRoots map[string]string `yaml:"worktree-roots" json:"worktreeRoots"`
IntegrationProvider string `yaml:"integration-provider" json:"integrationProvider"`
IntegrationNetworkPolicy IntegrationNetworkPolicy `yaml:"integration-network-policy,omitempty" json:"integrationNetworkPolicy"`
}
TaskRuntimeConfig declares repository-owned runtime configuration.