pkg

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 14, 2026 License: BSD-2-Clause Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const (
	PlanOutcomeReady          = "ready"
	PlanOutcomeNoUpdateNeeded = "no_update_needed"
	PlanOutcomeNeedsInput     = "needs_input"
)

Outcome values for PlanOutput.Outcome.

View Source
const (
	VulnActionFix  = "fix"
	VulnActionPark = "park"
)

Action values for PlanVuln.Action.

View Source
const (
	ResultOutcomeOpened         = "opened"
	ResultOutcomeAdopted        = "adopted"
	ResultOutcomeNoUpdateNeeded = "no_update_needed"
	ResultOutcomeFailed         = "failed"
)

Outcome values for ResultOutput.Outcome.

View Source
const AgentLogin = "github-update-go-agent"

AgentLogin is the GitHub-task-system identity of this agent. Per the platform doctrine the CONTROLLER writes previous_assignee — the constant exists for logs and messages only; steps never mutate assignee.

Variables

This section is empty.

Functions

func BuildEnv

func BuildEnv(
	ghToken, anthropicBaseURL, anthropicAuthToken, anthropicModel string,
) map[string]string

BuildEnv assembles the env map forwarded into the Claude CLI subprocess. Only set values are forwarded so the subprocess sees a clean env. Shared by both the Kafka entry point (main.go) and the local-CLI entry point (cmd/run-task/main.go).

GH_TOKEN is threaded explicitly because the ClaudeRunner strips the pod env to an allowlist — os.Setenv alone does not reach the Claude subprocess.

func NewClaudeAuthStep

func NewClaudeAuthStep(prober ClaudeProber) agentlib.Step

NewClaudeAuthStep wires the claude-auth preflight with its prober seam.

func NewExecutionStep

func NewExecutionStep(
	runner claudelib.ClaudeRunner,
	ops git.GitOps,
	gh GhCli,
	gate GateRunner,
	ghToken string,
) agentlib.Step

NewExecutionStep wires the execution step with its four seams: the Claude runner (update + repair sub-call), the GitOps seam (clone/branch/commit/ push), the gh CLI seam (draft PR create + adopt), and the gate runner (deterministic green-gate re-run).

func NewGHTokenCheckStep

func NewGHTokenCheckStep(ghToken string) agentlib.Step

NewGHTokenCheckStep constructs the preflight step. ghToken is the resolved token from startup auth (passed by main → factory). Empty means the step fails fast on the first run.

func NewPlanningStep

func NewPlanningStep(
	runner claudelib.ClaudeRunner,
	ops git.GitOps,
	ghToken string,
	scope InstallationScope,
) agentlib.Step

NewPlanningStep wires the planning step with its Claude runner (inspection LLM), the GitOps seam (clone at ref), the GitHub token (HTTPS auth URL transformation), and the installation-scope allowlist check.

func NewReviewStep

func NewReviewStep(
	ops git.GitOps,
	gh GhCli,
	gate GateRunner,
	ghToken string,
) agentlib.Step

NewReviewStep wires the ai_review verifier with its GitOps seam (fresh clone + tag/rev inspection), gh CLI seam (PR state), gate runner (independent gate re-run), and the GitHub token.

Types

type ClaudeProber

type ClaudeProber interface {
	// Probe returns nil when claude is authenticated and reachable, or an
	// error describing the failure otherwise.
	Probe(ctx context.Context) error
}

ClaudeProber runs a trivial claude invocation to confirm the CLI is authenticated before any prompt-bearing phase runs.

func NewClaudeProber

func NewClaudeProber(claudeConfigDir claudelib.ClaudeConfigDir) ClaudeProber

NewClaudeProber constructs a ClaudeProber that shells out to `claude --print`. claudeConfigDir, when non-empty, is exported as CLAUDE_CONFIG_DIR so the probe reads the same login the agent will.

type GateRunner

type GateRunner interface {
	// RunTarget runs `make <target>` in workdir. Returns the bounded
	// combined-output tail, the process exit code (0 on success), and a
	// non-nil error when the target failed or could not be started.
	RunTarget(ctx context.Context, workdir, target string) (tail string, exitCode int, err error)
}

GateRunner runs one repo gate target (`make -C <workdir> <target>`) and reports the exit code plus a bounded output tail. The execution step uses it as the deterministic green-gate after the Claude sub-call; the ai_review step re-runs the same targets independently.

func NewOSExecGateRunner

func NewOSExecGateRunner() GateRunner

NewOSExecGateRunner returns a GateRunner shelling out to make. The gate inherits the full pod env (os.Environ()): repo Makefiles run scanners via `go run tool@version`, which needs GOPROXY/GOPATH/HOME plus GH_TOKEN for private module fetches — the design accepts in-pod arbitrary code execution for own repos (design § 7.2).

type GhCli

type GhCli interface {
	// CreateDraftPR opens a DRAFT pull request from head against base,
	// running gh inside workdir so the repo is inferred from the git
	// remote. Returns the PR URL.
	CreateDraftPR(ctx context.Context, workdir, base, head, title, body string) (string, error)

	// FindOpenPRByHead returns the URL of an open PR whose head is the
	// given branch, or "" when none exists. repo is "owner/name".
	FindOpenPRByHead(ctx context.Context, repo, head string) (string, error)

	// ViewPR returns the state (e.g. "OPEN", "MERGED", "CLOSED") and
	// draft flag of the PR identified by URL.
	ViewPR(ctx context.Context, prURL string) (state string, isDraft bool, err error)
}

GhCli is the seam between the steps and the gh binary. Three methods cover the agent's entire PR surface: create a DRAFT PR, adopt an already-open PR by head branch (crash-window replay guard), and view PR state for the ai_review checks.

Deliberately absent (design § 7.0): no Ready, no Merge — the agent never flips a draft and never merges; the human does.

func NewOSExecGhCli

func NewOSExecGhCli(ghToken string) GhCli

NewOSExecGhCli returns a GhCli implementation that shells out to the gh binary with a minimal allowlisted env (GH_TOKEN, HOME, PATH).

type GoBump

type GoBump struct {
	From string `json:"from"`
	To   string `json:"to"`
}

GoBump records a go-directive version bump.

type InstallationScope added in v0.3.0

type InstallationScope interface {
	// Allows reports whether repo ("owner/name") is covered by the token's
	// installation. Unknown means the check itself was impossible — never
	// treat that as denial.
	Allows(ctx context.Context, repo string) ScopeVerdict
}

InstallationScope answers whether the GitHub App installation backing the agent's token covers a repo. The App installation's repository selection IS the fleet's per-stage allowlist (design § 7.2): a repo outside it must park in planning, before any clone/update work — not after ten minutes of work at the push step.

func NewGhInstallationScope added in v0.3.0

func NewGhInstallationScope(ghToken string) InstallationScope

NewGhInstallationScope returns an InstallationScope that shells out to `gh api /installation/repositories` with the agent's token. With an App installation token the endpoint lists exactly the accessible repos; with the local GH_TOKEN PAT fallback it 403s, which maps to ScopeUnknown (local runs are operator-supervised — no allowlist to enforce).

type PlanOutput

type PlanOutput struct {
	Outcome string `json:"outcome"`

	// HasWork is true when the execution phase has anything to do.
	// omitempty is deliberately NOT applied so a `false` decision is
	// always written explicitly.
	HasWork bool `json:"has_work"`

	// GoBump records the go-directive bump (from current directive to the
	// image toolchain per design D5). Nil when the directive is already
	// current.
	GoBump *GoBump `json:"go_bump,omitempty"`

	// DepUpdatesExpected is true when `go list -u -m` style inspection
	// found outdated direct dependencies.
	DepUpdatesExpected bool `json:"dep_updates_expected"`

	// GateTargets are the Makefile targets forming the repo's own gate
	// (e.g. precommit, check, vulncheck). Execution and ai_review re-run
	// exactly these to exit 0 — never a hardcoded scanner.
	GateTargets []string `json:"gate_targets,omitempty"`

	// Vulns holds every scanner finding with its fix-vs-park classification.
	Vulns []PlanVuln `json:"vulns,omitempty"`

	// Reason carries the human-readable explanation on the
	// needs_input / no_update_needed paths.
	Reason string `json:"reason,omitempty"`
}

PlanOutput is the typed contract for the `## Plan` JSON section the planning step writes for every github-update-go task. Round-trips with agentlib.MarshalSectionTyped + agentlib.ExtractSection[PlanOutput].

Shapes (design § 4.3):

  • Outcome="ready" — update work exists; GateTargets populated, HasWork=true
  • Outcome="no_update_needed" — repo already current; HasWork=false
  • Outcome="needs_input" — park path (unfixable finding / precondition); Reason populated

No `Details map[string]any`: concrete fields only. Future fields require a design amendment.

type PlanVuln

type PlanVuln struct {
	// ID is the finding identifier (GO-*, CVE-*, GHSA-*).
	ID string `json:"id"`
	// Package is the vulnerable module path.
	Package string `json:"package,omitempty"`
	// FixedVersion is the patched version the scanner reported; empty when
	// no fix exists (the park case).
	FixedVersion string `json:"fixed_version,omitempty"`
	// Scanner names which gate scanner flagged the finding
	// (govulncheck | osv-scanner | trivy).
	Scanner string `json:"scanner,omitempty"`
	// Action is "fix" (patched version exists — bump it) or "park"
	// (no fix / out-of-scope major — task parks per design D4).
	Action string `json:"action"`
	// Reason is the one-line classification justification.
	Reason string `json:"reason,omitempty"`
}

PlanVuln is one scanner finding with its planned action.

type ResultOutput

type ResultOutput struct {
	Outcome string `json:"outcome"`
	Branch  string `json:"branch,omitempty"`
	PRURL   string `json:"pr_url,omitempty"`

	// GateExit is the exit code of the last gate target run (0 = green).
	// omitempty is deliberately NOT applied — an explicit 0 documents the
	// green gate.
	GateExit int `json:"gate_exit"`

	// DepsUpdated counts the module bumps the update sequence applied.
	DepsUpdated int `json:"deps_updated"`

	// VulnsFixed lists the finding IDs resolved by the update — always a
	// subset of the plan's fix-action vulns.
	VulnsFixed []string `json:"vulns_fixed,omitempty"`

	// FailedTarget names the gate target that stayed red (failure path only).
	FailedTarget string `json:"failed_target,omitempty"`

	ErrorCategory git.ErrorCategory `json:"error_category,omitempty"`
	Error         string            `json:"error,omitempty"`
}

ResultOutput is the typed contract for the `## Result` JSON section the execution step writes. Round-trips with agentlib.MarshalSectionTyped + agentlib.ExtractSection[ResultOutput].

Shapes (design § 4.3):

  • Outcome="opened" — draft PR created; Branch/PRURL populated, GateExit=0
  • Outcome="adopted" — crash-window replay found the PR already open; adopted as-is
  • Outcome="no_update_needed" — the update sequence produced no effective change (workdir diff empty or CHANGELOG.md-only) once MVS settled; no commit/push/PR, workdir discarded (go-skeleton PR #51 guard)
  • Outcome="failed" — any failure; ErrorCategory + Error populated

Invariant (design § 4.4): Branch == "fix/update-go-" + ref[:7]; VulnsFixed ⊆ {v.ID | v ∈ Plan.Vulns, Action=fix}.

type ReviewChecks

type ReviewChecks struct {
	// PROpen — `gh pr view` reports state OPEN.
	PROpen bool `json:"pr_open"`
	// PRDraft — `gh pr view` reports isDraft true (the agent never readies).
	PRDraft bool `json:"pr_draft"`
	// GateGreen — every planned gate target re-ran to exit 0 on a fresh
	// worktree at the branch.
	GateGreen bool `json:"gate_green"`
	// VulnsClear — the scanner-bearing gate targets came back green on the
	// re-run (the gate IS the vuln verdict, per design § 7.3 the repo's
	// gate wraps govulncheck/osv-scanner/trivy).
	VulnsClear bool `json:"vulns_clear"`
	// ChangelogUnreleased — CHANGELOG.md carries a bullet under
	// ## Unreleased and introduces no new version header vs master.
	ChangelogUnreleased bool `json:"changelog_unreleased"`
	// NoNewTag — `git ls-remote --tags` shows no tag pointing at any
	// branch commit.
	NoNewTag bool `json:"no_new_tag"`
}

ReviewChecks holds the boolean verification results of the pure-Go ai_review step. Every field is derived from independent re-execution — never copied from ## Result (design § 4.4).

type ReviewOutput

type ReviewOutput struct {
	Approved bool         `json:"approved"`
	Checks   ReviewChecks `json:"checks"`
	Notes    string       `json:"notes"`
}

ReviewOutput is the typed contract for the `## Review` JSON section the ai_review step writes. Round-trips with agentlib.MarshalSectionTyped + agentlib.ExtractSection[ReviewOutput].

type ScopeVerdict added in v0.3.0

type ScopeVerdict string

ScopeVerdict is the outcome of an installation-scope check.

const (
	// ScopeAllowed — the repo is in the App installation's repository list.
	ScopeAllowed ScopeVerdict = "allowed"
	// ScopeDenied — the installation token definitively cannot access the repo.
	ScopeDenied ScopeVerdict = "denied"
	// ScopeUnknown — the check could not be performed (PAT fallback, API
	// error). Callers proceed; a real permission gap still fails at push.
	ScopeUnknown ScopeVerdict = "unknown"
)

Directories

Path Synopsis
Package factory wires concrete dependencies for the github-update-go-agent binary.
Package factory wires concrete dependencies for the github-update-go-agent binary.
Package git wraps git shell-outs behind the GitOps interface so the execution and ai_review steps can be tested with a counterfeiter mock.
Package git wraps git shell-outs behind the GitOps interface so the execution and ai_review steps can be tested with a counterfeiter mock.
Package githubauth resolves the github-update-go agent's effective GitHub credential at startup.
Package githubauth resolves the github-update-go agent's effective GitHub credential at startup.
Package prompts provides embedded prompt modules for the Claude-backed phases: planning (inspect + classify) and execution (update + repair).
Package prompts provides embedded prompt modules for the Claude-backed phases: planning (inspect + classify) and execution (update + repair).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL