Documentation
¶
Overview ¶
Package orchestrate runs typed repository mutations through isolated worktrees, local verification, and optional GitHub publication stages.
Index ¶
- Constants
- Variables
- func MatchesHold(slug string, patterns []string) bool
- func PullRequestNumber(selector string) (string, error)
- func RepositoryFromPullRequestURL(pullRequestURL string) (string, error)
- type Assessment
- type CIFailureDetail
- type ChangedFile
- type FetchMemo
- type Handler
- type HeadCheck
- type LandOutcome
- type LandedCommit
- type MechanicalVerdict
- type MergeLaneClaim
- type OperationLock
- type Options
- type PullRequestLandOptions
- type PullRequestLandResult
- type PullRequestView
- type PullRequestWaitOptions
- type PullRequestWaitProgress
- type PullRequestWaitResult
- type PullRequestWaitStatus
- type RemoteCheck
- type Repository
- type RequiredRemoteCheck
- type ResolvedBase
- type Result
- type SourceCommit
- type WorktreeMergeCandidate
- type WorktreeMergeConflictCandidateAdvance
- type WorktreeMergeConflictCandidateRefresh
- type WorktreeMergeConflictCandidateRefreshOptions
- type WorktreeMergeForwardRepairReceipt
- type WorktreeMergeLandOptions
- type WorktreeMergeLandedFailureAcknowledgement
- type WorktreeMergeLandedFailureAcknowledgementOptions
- type WorktreeMergeLegacyValidationFailureIdentity
- type WorktreeMergeMissingCleanupAcknowledgement
- type WorktreeMergeMissingCleanupAcknowledgementOptions
- type WorktreeMergePhase
- type WorktreeMergePrepareOptions
- type WorktreeMergePreparedRebatch
- type WorktreeMergePublishedCandidateAdoption
- type WorktreeMergePublishedCandidateAdoptionOptions
- type WorktreeMergePublishedForwardRepair
- type WorktreeMergePublishedForwardRepairOptions
- type WorktreeMergePushGateReceipt
- type WorktreeMergeRebaseReceipt
- type WorktreeMergeReceipt
- func LandWorktreeMerge(ctx context.Context, options WorktreeMergeLandOptions) (WorktreeMergeReceipt, error)
- func PrepareWorktreeMerge(ctx context.Context, options WorktreeMergePrepareOptions) (WorktreeMergeReceipt, error)
- func PrepareWorktreeMergeRevert(ctx context.Context, projectsRoot, input string, timeout time.Duration, ...) (WorktreeMergeReceipt, error)
- func ResumeWorktreeMerge(ctx context.Context, options WorktreeMergeLandOptions) (WorktreeMergeReceipt, error)
- func RunWorktreeMerge(ctx context.Context, prepare WorktreeMergePrepareOptions, ...) (WorktreeMergeReceipt, error)
- type WorktreeMergeReceiptCollisionAcknowledgement
- type WorktreeMergeReceiptCollisionAcknowledgementOptions
- type WorktreeMergeRevertReceipt
- type WorktreeMergeRoute
- type WorktreeMergeRouteDecision
- type WorktreeMergeSelfSupersessionCorrection
- type WorktreeMergeSelfSupersessionCorrectionOptions
- type WorktreeMergeSource
- type WorktreeMergeSourceRefresh
- type WorktreeMergeStatus
- type WorktreeMergeStrandedLandingAcknowledgement
- type WorktreeMergeStrandedLandingAcknowledgementOptions
- type WorktreeMergeValidationFailureSeal
- type WorktreeMergeValidationFailureSealOptions
- type WorktreeMergeValidationFailureSealRoot
- type WorktreeMergeValidationFailureSupersession
- type WorktreeMergeValidationFailureSupersessionOptions
- type WorktreeMergeValidationIdentity
- type WorktreeMergeValidationTimeouts
Constants ¶
const ( LandRefusalDraft = "draft-pull-request" LandRefusalNotOpen = "pull-request-not-open" LandRefusalLocked = "pull-request-locked" LandRefusalHeadMoved = "head-moved" LandRefusalNotMergeable = "not-mergeable" LandRefusalUnapprovedPatch = "unapproved-patch-set" LandRefusalChecksPending = "checks-pending" LandRefusalChecksFailed = "checks-failed" LandRefusalMergeRejected = "merge-rejected" LandRefusalLandingUnverified = "landing-unverified" LandRefusalUnfencedTarget = "target-has-no-strict-fence" LandRefusalCanonicalSync = "canonical-sync-blocked" )
LandRefusal codes are the machine-readable half of a refusal. A caller branches on these rather than on prose.
const ( LandRefusalKeepReasonMissing = "keep-commits-without-reason" LandRefusalKeepUnknownCommit = "keep-commit-not-on-branch" LandRefusalKeepDoesNotBuild = "kept-commit-does-not-build" LandRefusalKeepNeedsCheckout = "keep-commits-needs-local-checkout" )
LandRefusalKeepReasonMissing and friends are the refusals specific to a partially kept landing.
const DefaultCheckPollInterval = 30 * time.Second
DefaultCheckPollInterval deliberately leaves room for other WB operations sharing the authenticated GitHub user budget. A PR receipt still reads every dynamic fact on each observation; only static branch policy is cached within the bounded slice and is fetched again before a pass is returned.
const FetchMemoMaxAge = 15 * time.Minute
FetchMemoMaxAge bounds how long one memoized `git fetch origin` may stand in for a new one within a run. Discovery over a large fleet plus a full wave of CI waits can hold a campaign open for hours; without a bound, one early fetch of an untouched repository would be trusted for that whole span. With the bound, an external writer's mid-campaign push to an untouched repository is observed within this window at the latest, while nearly all of the per-wave discovery saving is kept (waves separated by less than the bound still skip).
const MaxForegroundCheckWaitSlice = 9 * time.Minute
MaxForegroundCheckWaitSlice keeps a single agent-tool call under the common ten-minute harness ceiling. Longer CI is observed by explicit re-invocation, never a detached worker or a hidden thirty-minute loop.
const WorktreeMergeSchemaVersion = 1
Variables ¶
var DefaultStableRereadDelay = 15 * time.Second
DefaultStableRereadDelay bounds the wait before the confirming reread of a checks-bearing terminal observation. The stability fingerprint exists to catch a check set that is still registering, not to space out load: once every observed and required check is terminal, only this one confirming observation (plus the fresh authority and identity receipts) stands between the campaign and its receipt, so waiting a full quota-aware poll interval there adds DefaultCheckPollInterval of pure latency to every passing PR merge, PR validation, and direct-target receipt. Fifteen seconds sits outside GitHub's usual push-to-registration envelope for lazily created non-required checks (matrix expansion, workflow_run chains) while still cutting half the default cadence. It is a variable, and PullRequestWaitOptions.StableRereadDelay overrides it per wait, so tests and unusual deployments can tune it without recompiling callers.
Two terminal receipts never shorten this wait: the no-applicable-checks receipt (an empty observed set with an enumerated empty policy), whose only time-based guard against a repository whose CI simply has not registered yet IS this gap, and any reread after the previous observation was already terminal — a churning terminal fingerprint (for example a moving target head) falls back to the full poll cadence instead of re-observing on the short delay without bound.
Functions ¶
func MatchesHold ¶ added in v0.82.0
MatchesHold reports whether an "owner/name" repository slug matches any hold pattern. Patterns use path.Match semantics, where "*" never crosses a "/", so "sneat-co/*" holds every repository in one owner and "sneat-co/sneat-go" holds exactly one. An exact string equal to the slug always matches, so a caller never has to think about glob metacharacters in a literal repository name.
func PullRequestNumber ¶ added in v0.89.0
PullRequestNumber accepts every spelling a caller already has in hand — a bare number, "#12", "owner/repo#12", or the pull request's own URL — and returns the number the API is addressed by. Callers hold whichever form their own source gave them, and making each one normalize it separately is how a URL reaches an endpoint path and produces a 404 that reads like a missing pull request.
func RepositoryFromPullRequestURL ¶ added in v0.89.0
RepositoryFromPullRequestURL extracts owner/repository from a pull request URL, so a caller holding only the URL can still address the API.
Types ¶
type Assessment ¶
Assessment is adapter-owned planning metadata plus an execution decision.
type CIFailureDetail ¶ added in v0.98.0
type CIFailureDetail struct {
Check string `json:"check" yaml:"check"`
RunURL string `json:"run_url,omitempty" yaml:"run_url,omitempty"`
JobURL string `json:"job_url,omitempty" yaml:"job_url,omitempty"`
Excerpt string `json:"excerpt,omitempty" yaml:"excerpt,omitempty"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
}
CIFailureDetail is a bounded diagnostic for one failed GitHub Actions job. It deliberately carries an excerpt rather than the raw job log so a machine receipt remains compact and does not become an accidental log archive.
type ChangedFile ¶ added in v0.89.0
type ChangedFile struct {
Filename string `json:"filename"`
Status string `json:"status"`
Patch string `json:"patch"`
}
ChangedFile is one file of a pull request's diff, with the patch GitHub returns for it.
type FetchMemo ¶ added in v0.74.0
type FetchMemo struct {
// contains filtered or unexported fields
}
FetchMemo memoizes `git fetch origin` per canonical clone within one process-local run, so a campaign loop that alternates fleet-wide discovery and per-wave mutation (wb deps bump) does not pay one fetch per repository per wave for repositories the run itself never wrote to.
Only read-only graph discovery may consume the memo (see Options.FetchMemoDiscovery): the mutation engine always re-fetches before cutting a branch, so a wave's base ref is never a snapshot up to one discovery pass old. The engine still records its fetches here and drives the touch-invalidation below.
The invalidation rule is deliberately "ever touched", not "wrote since the last fetch": once this run has pushed a branch to, opened a pull request for, or merged into a repository, that repository is permanently un-memoizable for the rest of the run. WB merges server-side with `gh pr merge`, so the resulting default-branch commit appears on origin with no local push at all — an own-writes rule keyed on observed local pushes would provably miss it, and a stale origin/<ref> read then either never observes the landed manifest (burning waves until --max-waves fails the campaign) or cuts a duplicate PR from the stale base. Re-fetching a touched repository on every subsequent EnsureCanonical costs one redundant fetch per wave for the handful of repositories a wave actually changed; it can never serve a stale read.
Honest staleness window: this memo widens exposure to EXTERNAL writers. A teammate's merge, a sibling campaign, or a bot landing on an untouched repository's default branch mid-run is observed within one wave WITHOUT the memo, but only within FetchMemoMaxAge WITH it. That is the flag's real trade — which is why it is opt-in, why the age bound exists, and why the skill docs say not to use --fetch-cache when anything other than this run may land on main mid-campaign.
State is process-local only: a memo lives exactly as long as the run that created it, is never persisted, and a fresh invocation always fetches. Keys are canonical clone directories (not owner/repo slugs), so two directories that happen to claim one slug can never satisfy each other's fetches. A nil *FetchMemo is valid and disables memoization entirely (every method is a no-op / zero), which keeps every caller that does not thread a memo — deps set, worktree operations, all non-campaign engines — byte-identical to the pre-memo behavior.
func NewFetchMemo ¶ added in v0.74.0
func NewFetchMemo() *FetchMemo
NewFetchMemo returns an empty per-run fetch memo.
func (*FetchMemo) MarkFetched ¶ added in v0.74.0
MarkFetched records that this run completed `git fetch origin` for the canonical clone, refreshing its age. A clone already marked touched is deliberately not re-memoized: touched repositories stay un-memoizable for the rest of the run regardless of how many times they are fetched again.
func (*FetchMemo) MarkTouched ¶ added in v0.74.0
MarkTouched permanently disqualifies the canonical clone from fetch memoization for the rest of this run. It is called before every stage that publishes state for the repository — branch push, pull-request creation, and the server-side merge — so a failed or ambiguous publication also invalidates (the only cost of over-invalidating is one extra fetch).
func (*FetchMemo) SkipFetch ¶ added in v0.74.0
SkipFetch reports whether a discovery pass may reuse this run's previous fetch of the canonical clone: it was fetched no longer than FetchMemoMaxAge ago and has never been touched. A nil memo never skips. Each true result is counted for the campaign report (see Skips).
type Handler ¶
type Handler[T any] interface { Inspect(context.Context, string, string, Repository) (Assessment[T], error) Apply(context.Context, string, Repository) (T, error) ValidatePublishable(context.Context, string, Repository) error CommitMessage(Repository) string PullRequest(Repository) (title, body string) }
Handler supplies mutation policy while Engine owns repository lifecycle.
type HeadCheck ¶ added in v0.89.0
HeadCheck is one observed check on a commit, in the shape a caller outside this package needs: a name and a normalized bucket.
func PullRequestHeadChecks ¶ added in v0.89.0
func PullRequestHeadChecks(ctx context.Context, repository, selector string) ([]HeadCheck, bool, error)
PullRequestHeadChecks reads every check GitHub has for a pull request's current head, and reports whether they have all passed.
It exists so there is exactly one implementation of "are this pull request's checks green?" in WB, reachable from outside this package. The alternative — `gh pr checks --json` — is unavailable on the installed client, and even where it works it is a second dialect for a fact the API already answers.
type LandOutcome ¶ added in v0.89.0
type LandOutcome string
LandOutcome is the envelope outcome. It maps onto the exit-code contract: success is 0, findings is 1, refused is 2.
const ( LandSuccess LandOutcome = "success" LandFindings LandOutcome = "findings" LandRefused LandOutcome = "refused" )
type LandedCommit ¶ added in v0.89.0
type LandedCommit struct {
SourceSHA string `json:"source_sha"`
LandedSHA string `json:"landed_sha,omitempty"`
Subject string `json:"subject"`
Kept bool `json:"kept"`
}
LandedCommit pairs a source commit with the commit that carried it onto the base. GitHub's rebase merge always rewrites the commits, so after landing these pairs are the only way back to the originals.
func MapLandedCommits ¶ added in v0.89.0
func MapLandedCommits(ctx context.Context, canonical, base, mergeBase string, landed []LandedCommit) ([]LandedCommit, error)
MapLandedCommits pairs each source commit with the commit that carried it onto the base, by patch identity.
GitHub's rebase merge replays every commit with new committer metadata and new SHAs, so the only durable link back to a source commit is the content it carried. `git patch-id --stable` is that link: it hashes the diff, ignoring whitespace-insensitive noise and every piece of metadata a replay rewrites.
The aggregated sources all map to the one commit that absorbed them, which is found by elimination: it is the landed commit no kept source claims.
type MechanicalVerdict ¶ added in v0.89.0
type MechanicalVerdict struct {
Mechanical bool
// Reasons name each file that made the change non-mechanical, and why.
Reasons []string
// NonManifest is the subset of Reasons that is just "this is code".
NonManifest []string
}
MechanicalVerdict explains a classification well enough to argue with.
func ClassifyMechanical ¶ added in v0.89.0
func ClassifyMechanical(files []ChangedFile) MechanicalVerdict
ClassifyMechanical decides from the diff whether a change is a mechanical dependency bump.
func (MechanicalVerdict) Summary ¶ added in v0.89.0
func (verdict MechanicalVerdict) Summary() string
Summary renders the verdict for a refusal.
type MergeLaneClaim ¶ added in v0.73.0
type MergeLaneClaim struct {
// Lane identifies the exclusive (repository, target) merger lane that
// claimed the branch.
Lane string `json:"lane"`
// Target is the branch the lane is draining toward.
Target string `json:"target"`
// Status is the receipt's current lifecycle status (see
// WorktreeMergeStatus), e.g. "prepared" or "checks_pending".
Status string `json:"status"`
// ReceiptPath is the exact local receipt backing the claim, so a caller
// can inspect the full batch (wb worktree merge land <receipt>).
ReceiptPath string `json:"receipt_path"`
}
MergeLaneClaim reports that a branch is currently a source of a non-terminal merger-lane receipt: some merger lane has already selected it as an input to a batch it may land at any time. See the lesson merger-lane-branch-race (spec/lessons/merger-lane-branch-race in sneat-co/backstage): a branch with an open PR is not a private workspace once a lane owns it, and neither PR state, reviews, nor CI surface that fact to a main agent deciding whether to push.
func ActiveMergeLaneClaim ¶ added in v0.73.0
func ActiveMergeLaneClaim(projectsRoot, repository, branch string) (*MergeLaneClaim, error)
ActiveMergeLaneClaim reports whether branch in repository is a source of an active (non-terminal, non-superseded) merger-lane receipt, regardless of which target that lane is draining toward — a main agent about to push does not necessarily know the target a lane already chose. It returns a nil claim, not an error, when no active receipt claims the branch or when no merger has ever run for this WB home (a fresh reports directory).
type OperationLock ¶
type OperationLock struct {
// contains filtered or unexported fields
}
OperationLock prevents two processes from mutating the same operation worktrees. Higher-level planners may hold a campaign lock while individual lifecycle runs also protect their wave directories.
func AcquireOperationLock ¶
func AcquireOperationLock(githubDir, operation string, resume bool) (OperationLock, error)
AcquireOperationLock creates an exclusive lock below the operation root. An unheld remnant is reclaimable only by an explicit resume and only when its descriptor proves exact ownership of this operation.
func (OperationLock) Release ¶
func (lock OperationLock) Release() error
Release retires the exact held lock inode. It is safe to call from defer and cannot unlink a successor lock installed after this operation acquired one.
type Options ¶
type Options struct {
GitHubDir string
Operation string
Branch string
Ref string
Parallel int
DryRun bool
Resume bool
Verify bool
Checks []quality.Check
Timeout time.Duration
Retry int
// CheckPollInterval overrides the GitHub-check polling delay. A zero value
// uses the production default. It is primarily useful for deterministic
// lifecycle tests.
CheckPollInterval time.Duration
Commit bool
Push bool
PR bool
Merge bool
// WaitForPRChecks observes exact PR-head checks after opening a pull
// request, but deliberately does not merge it. It is only valid with PR
// publication and is intended for validation-only campaigns.
WaitForPRChecks bool
// Hold is a set of "owner/name" glob patterns naming repositories whose
// merge is a human decision. A held repository is changed, verified,
// pushed, has its pull request opened, and has its exact PR-head checks
// waited on exactly like any other — and is then left OPEN, even under
// Merge. It is not a way to skip a repository (that is the caller's own
// exclusion, applied before this engine sees the repository); it is a way
// to do all the mechanical work and stop at the one step that needs an
// owner's judgement, such as a deploy repository the founder gates.
Hold []string
Progress progress.Reporter
// Prompt is recorded as the originating instruction in the WB manifest
// journal of every worktree this operation creates, satisfying wb's own
// commit-admission hook (internal/worktrees.CheckAdmission) — without it,
// a worktree this engine creates and then commits into is rejected by
// wb's own pre-commit hook as carrying no record of what it is or who
// asked for it. Normalize fills in an operation-derived default when
// empty, so every caller gets a truthful record even if it has nothing
// more specific to say.
Prompt string
// Model, AgentRuntime, Initiator, CLI, and Provider identify who or what
// asked for this operation, recorded in the same manifest for
// provenance. Normalize defaults Model to "unknown" when empty, matching
// the same explicit-over-guessed convention used everywhere else a
// child model identity is recorded (see internal/worktrees.WorkLogOptions).
Model string
AgentRuntime string
Initiator string
CLI string
Provider string
// DependencyCampaign marks worktrees created by dependency set/bump
// campaigns. Their supersession receipts require exact dependency proof.
DependencyCampaign bool
// FetchMemo, when non-nil, memoizes this run's completed origin fetches
// and receives touch-invalidation from the push, PR-open, and merge
// stages (see FetchMemo). Only a campaign loop that alternates fleet-wide
// discovery and mutation over the same repositories within one process —
// wb deps bump with --fetch-cache — threads one memo through every
// discovery and wave lifecycle it runs. Every other caller leaves it nil
// and keeps the unconditional engine fetch: for deps set --fleet there is
// no prior discovery, so that fetch is the operation's only origin read
// and must never be skipped.
FetchMemo *FetchMemo
// FetchMemoDiscovery marks this lifecycle as read-only graph discovery,
// which is the ONLY context allowed to consume the memo: EnsureCanonical
// may then skip a fresh, untouched memoized fetch. The mutation engine
// leaves it false even when FetchMemo is threaded, so a wave's branch
// base is always cut from a fetch completed moments before — never from a
// snapshot up to one full discovery pass old, which would interact badly
// with strict up-to-date branch protection and exact-head merges. The
// engine's own fetches still refresh the memo, and its publication
// stages still invalidate through it.
FetchMemoDiscovery bool
}
Options controls a repository operation independently of mutation policy.
type PullRequestLandOptions ¶ added in v0.89.0
type PullRequestLandOptions struct {
Repository string
PullRequest string
ProjectsRoot string
// Keep retains the task's worktrees and claims. Cleanup is the default
// precisely because the opt-in form was never passed.
Keep bool
// ApprovedBy records the review that authorized a non-mechanical change: a
// review file path or a pull-request comment URL. The durable review ledger
// is a later phase; until it exists this value is recorded verbatim on the
// receipt so the approval is at least attributable.
ApprovedBy string
// MergeMethod is merge by default: preserve commits and the reviewed PR boundary.
MergeMethod string
// MergeMethodExplicit distinguishes an operator-selected method from the merge
// default. KeepCommits requires an explicitly selected squash hybrid.
MergeMethodExplicit bool
// Subject overrides the explicit squash commit subject. The default is the pull
// request's own title, which is the thing GitHub will otherwise replace
// with the branch's first commit subject.
Subject string
// KeepCommits names source commits that must land as their own commits
// instead of being folded into the aggregate. Reason is mandatory with it:
// the exception has to be justified in the history it creates.
KeepCommits []string
Reason string
// BuildCommand overrides the per-kept-commit build guard. Empty uses the
// repository's own target, which is `go build ./...` for a Go module.
BuildCommand []string
// AllowUnfenced lands on observed checks alone, where the target branch has
// no server-enforced strict up-to-date policy. Without such a fence, green
// checks prove the head was green, not that it is still green against the
// target the merge will use, so this is an explicit widening rather than a
// default — and the receipt records that it was used.
AllowUnfenced bool
// Slice is the total foreground wait budget retained under its historical
// name for API compatibility. A landing may outlive the bounded CI waiter:
// WB divides this budget into exact-identity observation slices instead of
// rejecting an otherwise valid long-running landing.
Slice time.Duration
CheckPollInterval time.Duration
Progress func(PullRequestWaitProgress)
OperationProgress progress.Reporter
// Events receives one structured record per invocation, whatever the
// outcome. A refusal is the most useful event of all — it is the one that
// says a verb was reached and declined — so `--keep` and every refusal
// write one too. A nil appender discards.
Events streams.EventAppender
// Stream names the stream this landing belongs to, when it belongs to one.
Stream string
Now func() time.Time
// contains filtered or unexported fields
}
PullRequestLandOptions identifies one pull request to land.
type PullRequestLandResult ¶ added in v0.89.0
type PullRequestLandResult struct {
SchemaVersion int `json:"v"`
Verb string `json:"verb"`
Outcome LandOutcome `json:"outcome"`
RefusalCode string `json:"refusal_code,omitempty"`
// SanctionedCommand is the exact command that satisfies the guard that
// fired. A refusal an agent cannot resolve becomes a hand-written
// workaround, which is how the cleanup path was bypassed in the first place.
SanctionedCommand string `json:"sanctioned_command,omitempty"`
Reason string `json:"reason,omitempty"`
Repository string `json:"repository"`
PullRequest int `json:"pull_request"`
URL string `json:"url,omitempty"`
Title string `json:"title,omitempty"`
HeadRef string `json:"head_ref,omitempty"`
HeadSHA string `json:"head_sha,omitempty"`
BaseRef string `json:"base_ref,omitempty"`
MergeSHA string `json:"merge_sha,omitempty"`
Subject string `json:"subject,omitempty"`
// Mechanical records the diff-derived classification and the files it was
// derived from, so a reader can check the judgement rather than trust it.
Mechanical bool `json:"mechanical"`
ChangedFiles []string `json:"changed_files,omitempty"`
NonManifest []string `json:"non_manifest_files,omitempty"`
ApprovedBy string `json:"approved_by,omitempty"`
Checks *PullRequestWaitResult `json:"checks,omitempty"`
BranchDeleted bool `json:"branch_deleted"`
LandingOnBase bool `json:"landing_on_base"`
CanonicalSync string `json:"canonical_sync,omitempty"`
// Commits pairs every source commit with the commit that landed it, and
// marks the ones kept separate. GitHub's rebase merge rewrites the SHAs, so
// after landing this pairing is the only way back to the originals.
Commits []LandedCommit `json:"commits,omitempty"`
KeptCommits []string `json:"kept_commits,omitempty"`
KeepReason string `json:"keep_reason,omitempty"`
CleanedTasks []string `json:"cleaned_tasks,omitempty"`
CleanupReports []string `json:"cleanup_reports,omitempty"`
Kept bool `json:"kept"`
// ManualEquivalent is the ordered list of calls a caller would otherwise
// have made. SavedToolCalls is that count minus one — the one call they
// made instead.
ManualEquivalent []string `json:"manual_equivalent"`
SavedToolCalls int `json:"saved_tool_calls"`
SavedTokensEstimate int `json:"saved_tokens_est"`
// AbsorbedPolls counts the check observations the verb waited through.
// Absorbing a poll loop is the largest single saving it makes.
AbsorbedPolls int `json:"absorbed_polls"`
Evidence map[string]string `json:"evidence,omitempty"`
}
PullRequestLandResult is the receipt, and the JSON envelope.
func LandPullRequest ¶ added in v0.89.0
func LandPullRequest(ctx context.Context, options PullRequestLandOptions) (result PullRequestLandResult, err error)
LandPullRequest verifies, merges, and tidies up after one pull request.
func (PullRequestLandResult) ExitCode ¶ added in v0.89.0
func (result PullRequestLandResult) ExitCode() int
ExitCode maps the outcome onto WB's exit contract.
func (PullRequestLandResult) FooterLine ¶ added in v0.89.0
func (result PullRequestLandResult) FooterLine() string
FooterLine is the interactive-mode summary. It is suppressed under --non-interactive, where the JSON envelope carries the same figures.
type PullRequestView ¶ added in v0.89.0
type PullRequestView struct {
Number int `json:"number"`
State string `json:"state"`
Draft bool `json:"draft"`
Locked bool `json:"locked"`
Title string `json:"title"`
Body string `json:"body"`
HTMLURL string `json:"html_url"`
Merged bool `json:"merged"`
MergedAt *time.Time `json:"merged_at"`
MergeCommitSHA string `json:"merge_commit_sha"`
// Mergeable is nil while GitHub is still computing the merge state. A nil
// is not a "no": it is "ask again", and a verb must not read it as either
// mergeable or conflicted.
Mergeable *bool `json:"mergeable"`
MergeableState string `json:"mergeable_state"`
Head struct {
Ref string `json:"ref"`
SHA string `json:"sha"`
Repo *struct {
FullName string `json:"full_name"`
} `json:"repo"`
} `json:"head"`
Base struct {
Ref string `json:"ref"`
SHA string `json:"sha"`
Repo *struct {
FullName string `json:"full_name"`
} `json:"repo"`
} `json:"base"`
}
PullRequestView is the pull-request state the land and merge verbs branch on. It is deliberately small: every field here is one a verb actually reads.
func ReadPullRequest ¶ added in v0.89.0
func ReadPullRequest(ctx context.Context, repository, selector string) (PullRequestView, error)
ReadPullRequest reads one pull request. It replaces `gh pr view --json`, which the installed client supports but which would still be a second dialect for the same fact.
type PullRequestWaitOptions ¶ added in v0.28.0
type PullRequestWaitOptions struct {
Repository string
PullRequest string
Target string
Head string
// AllowTargetDescendant is only for post-landing target CI: the exact
// landed Head must remain an ancestor of the observed target. Pre-landing
// candidate and pull-request waits retain exact target-head freshness.
AllowTargetDescendant bool
// AllowUnfenced permits a validation-only PR check receipt when the target
// branch has no server-enforced strict freshness fence. Merge callers leave
// this false; it is an explicit opt-in for wait-only validation.
AllowUnfenced bool
Slice time.Duration
CheckPollInterval time.Duration
// StableRereadDelay overrides the shortened wait before the confirming
// reread of a checks-bearing terminal observation. A zero value uses
// DefaultStableRereadDelay, and the delay never exceeds
// CheckPollInterval. The no-applicable-checks receipt and any reread
// after fingerprint churn always wait the full CheckPollInterval.
StableRereadDelay time.Duration
// Progress receives completed GitHub observations. It is diagnostic only;
// callers must use the returned result as the authoritative receipt.
Progress func(PullRequestWaitProgress)
OperationProgress progress.Reporter
}
PullRequestWaitOptions identifies exactly one direct-push or pull-request head whose observed checks are read by a bounded foreground invocation. A caller resumes a pending result with the same repository, target, PR (when supplied), and head; any later head is a distinct integration candidate.
type PullRequestWaitProgress ¶ added in v0.50.0
type PullRequestWaitProgress struct {
Observation int
Result PullRequestWaitResult
NextPoll time.Duration
}
PullRequestWaitProgress is one completed observation inside a bounded wait.
type PullRequestWaitResult ¶ added in v0.28.0
type PullRequestWaitResult struct {
Status PullRequestWaitStatus `json:"status" yaml:"status"`
Repository string `json:"repository" yaml:"repository"`
PullRequest string `json:"pull_request,omitempty" yaml:"pull_request,omitempty"`
Target string `json:"target" yaml:"target"`
Head string `json:"head" yaml:"head"`
ObservedHead string `json:"observed_head,omitempty" yaml:"observed_head,omitempty"`
ObservedTargetHead string `json:"observed_target_head,omitempty" yaml:"observed_target_head,omitempty"`
CandidateContainsTarget bool `json:"candidate_contains_target,omitempty" yaml:"candidate_contains_target,omitempty"`
TargetContainsHead bool `json:"target_contains_head,omitempty" yaml:"target_contains_head,omitempty"`
TargetFreshnessAuthority string `json:"target_freshness_authority,omitempty" yaml:"target_freshness_authority,omitempty"`
Checks []RemoteCheck `json:"checks,omitempty" yaml:"checks,omitempty"`
FailureDetails []CIFailureDetail `json:"failure_details,omitempty" yaml:"failure_details,omitempty"`
RequiredChecks []RequiredRemoteCheck `json:"required_checks,omitempty" yaml:"required_checks,omitempty"`
RequiredChecksAuthority string `json:"required_checks_authority,omitempty" yaml:"required_checks_authority,omitempty"`
UnfencedValidation bool `json:"unfenced_validation,omitempty" yaml:"unfenced_validation,omitempty"`
StableObservations int `json:"stable_observations" yaml:"stable_observations"`
Reason string `json:"reason,omitempty" yaml:"reason,omitempty"`
}
PullRequestWaitResult is one terminating foreground observation slice. Pending means resume is required, not that the merger is finished.
func WaitForCommitChecks ¶ added in v0.28.0
func WaitForCommitChecks(ctx context.Context, options PullRequestWaitOptions) (PullRequestWaitResult, error)
WaitForCommitChecks observes checks for one exact target commit. PullRequest is optional: when present it corroborates that exact PR head and target and augments the exact-head check-run/status receipt with GitHub's PR view. Every mode observes the exact commit through producer-aware APIs. Pending is an intermediate terminal result that callers resume with the same identity, not successful completion.
func WaitForPullRequestChecks ¶ added in v0.28.0
func WaitForPullRequestChecks(ctx context.Context, options PullRequestWaitOptions) (PullRequestWaitResult, error)
WaitForPullRequestChecks retains the original internal seam for existing orchestrated PR flows while using the exact-commit waiter above.
type PullRequestWaitStatus ¶ added in v0.28.0
type PullRequestWaitStatus string
PullRequestWaitStatus is intentionally small so callers can branch on a machine result instead of parsing human GitHub CLI output.
const ( PullRequestWaitPassed PullRequestWaitStatus = "passed" PullRequestWaitPending PullRequestWaitStatus = "pending" PullRequestWaitFailed PullRequestWaitStatus = "failed" )
type RemoteCheck ¶
type RemoteCheck struct {
Name string `json:"name" yaml:"name"`
Bucket string `json:"bucket" yaml:"bucket"`
Link string `json:"link,omitempty" yaml:"link,omitempty"`
AppID int64 `json:"app_id,omitempty" yaml:"app_id,omitempty"`
}
RemoteCheck is the normalized GitHub check state observed before merge.
type Repository ¶
Repository identifies a canonical clone selected by command-level discovery.
type RequiredRemoteCheck ¶ added in v0.28.0
type RequiredRemoteCheck struct {
Name string `json:"name" yaml:"name"`
IntegrationID int64 `json:"integration_id,omitempty" yaml:"integration_id,omitempty"`
}
RequiredRemoteCheck is GitHub's target-policy expectation. IntegrationID is non-zero when a ruleset pins the context to one GitHub App; every receipt must then observe the matching exact-head check-run producer, not merely a same-named PR summary or legacy status from another actor.
type ResolvedBase ¶ added in v0.59.2
type ResolvedBase struct {
// Ref is the short branch name (no "origin/" prefix).
Ref string
// Fallback is true when the operation's configured ref did not exist for
// this repository and Ref instead names its actual origin/HEAD default
// branch. Nothing about this is silent: every caller that receives a
// Fallback result is expected to surface it in its own report.
Fallback bool
}
ResolvedBase is the git ref EnsureCanonical verified exists in a repository's canonical clone. Every remaining lifecycle stage for this repository — graph inspection, worktree creation, and any eventual pull request base — must use Ref rather than the operation's configured options.Ref, since the two differ exactly when Fallback is true.
func EnsureCanonical ¶
func EnsureCanonical(ctx context.Context, repository Repository, canonical string, options Options) (ResolvedBase, error)
EnsureCanonical clones a missing repository, fetches origin, and verifies a usable base ref without checking out or modifying the canonical tree. It first tries the operation's configured options.Ref (default "main"); a fleet inevitably contains repositories whose default branch is something else (commonly "master", or a branch renamed after the local clone was made), so a repository that lacks options.Ref falls back to its actual origin/HEAD default branch instead of failing outright. A repository for which neither ref resolves still fails loudly — this is a fallback to a known-good alternative, never a silent skip.
type Result ¶
type Result[T any] struct { Repository string CanonicalDir string WorktreeDir string Branch string Ref string Status string Reason string Metadata T ChangedFiles []string Verifications []quality.VerificationEntry Commit string Pushed bool PR string Checks []RemoteCheck Merged bool // Held records that Options.Hold matched this repository, so its pull // request was deliberately left open for a human decision rather than // merged. It is never inferred from a failure. Held bool }
Result records lifecycle state and typed adapter metadata for one repository.
type SourceCommit ¶ added in v0.89.0
type SourceCommit struct {
SHA string `json:"sha"`
Subject string `json:"subject"`
Body string `json:"body,omitempty"`
}
SourceCommit is one commit of the pull request's branch.
type WorktreeMergeCandidate ¶ added in v0.66.0
type WorktreeMergeConflictCandidateAdvance ¶ added in v0.97.9
type WorktreeMergeConflictCandidateAdvance struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ReceiptID string `json:"receipt_id"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
ReceiptTargetSHA string `json:"receipt_target_sha"`
CurrentTargetSHA string `json:"current_target_sha"`
OriginalCandidate WorktreeMergeCandidate `json:"original_candidate"`
AdvancedCandidateSHA string `json:"advanced_candidate_sha"`
ClaimBaseSHA string `json:"claim_base_sha"`
Sources []WorktreeMergeSource `json:"sources"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeConflictCandidateAdvance is the append-only bridge between a conflict receipt's original candidate and the clean, manually resolved descendant. It is written before the mutable receipt is advanced to that descendant, so an interrupted resume cannot publish an unaudited head.
type WorktreeMergeConflictCandidateRefresh ¶ added in v0.97.7
type WorktreeMergeConflictCandidateRefresh struct {
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ImmutableClaimSHA256 string `json:"immutable_claim_sha256"`
CurrentTargetSHA string `json:"current_target_sha"`
ObservedCandidateDescendant string `json:"observed_candidate_descendant_sha,omitempty"`
Sources []WorktreeMergeSource `json:"sources"`
RequiredRoots []WorktreeMergeValidationFailureSealRoot `json:"required_roots"`
Candidate WorktreeMergeCandidate `json:"candidate"`
Actor string `json:"actor"`
Reason string `json:"reason"`
}
WorktreeMergeConflictCandidateRefresh is the unconsumed candidate created while a failed conflict receipt still owns its merger lane. The existing supersession acknowledgement remains the only transition that frees it.
func PrepareConflictWorktreeMergeReplacement ¶ added in v0.97.7
func PrepareConflictWorktreeMergeReplacement(ctx context.Context, options WorktreeMergeConflictCandidateRefreshOptions) (result WorktreeMergeConflictCandidateRefresh, retErr error)
PrepareConflictWorktreeMergeReplacement breaks only the cycle where a non-terminal, unpublished prepare conflict owns the lane that ordinary prepare would need to create the replacement. It writes no receipt or acknowledgement; callers pass the returned candidate to supersede-validation-failed.
type WorktreeMergeConflictCandidateRefreshOptions ¶ added in v0.97.7
type WorktreeMergeConflictCandidateRefreshOptions struct {
ProjectsRoot, Receipt, ExpectedReceiptSHA256, ExpectedImmutableClaimSHA256, ExpectedCurrentTargetSHA string
Sources, ExpectedSourceSHAs []string
Apply bool
Actor, Reason string
Model, AgentRuntime, AgentID, Initiator, CLI, Provider string
SessionRequired bool
Timeout time.Duration
Retry int
Progress progress.Reporter
}
func (WorktreeMergeConflictCandidateRefreshOptions) RefreshTask ¶ added in v0.97.7
func (options WorktreeMergeConflictCandidateRefreshOptions) RefreshTask() string
type WorktreeMergeForwardRepairReceipt ¶ added in v0.66.0
type WorktreeMergeForwardRepairReceipt struct {
Status WorktreeMergeStatus `json:"status"`
TargetSHA string `json:"target_sha"`
CandidateSHA string `json:"candidate_sha"`
LandingSHA string `json:"landing_sha"`
PullRequest string `json:"pull_request,omitempty"`
Checks PullRequestWaitResult `json:"checks"`
Failure string `json:"failure"`
}
WorktreeMergeForwardRepairReceipt preserves the exact landed attempt whose failed target CI required a new forward repair. The active lane reuses its candidate and receipt instead of abandoning either or pretending the prior remote landing never happened.
type WorktreeMergeLandOptions ¶ added in v0.66.0
type WorktreeMergeLandOptions struct {
ProjectsRoot string
Receipt string
Route WorktreeMergeRoute
Cleanup bool
OnFailure string
Timeout time.Duration
Retry int
CheckPollInterval time.Duration
Progress progress.Reporter
ProgressRequested bool
// StopBeforeMerge is the explicit PR-only handoff mode. It validates the
// preserved candidate and proves the remote open PR identity, then returns
// before CI observation or any merge operation. It is deliberately not
// persisted as future landing intent: a bare resume is how the merger takes
// over from the published handoff.
StopBeforeMerge bool
}
type WorktreeMergeLandedFailureAcknowledgement ¶ added in v0.69.2
type WorktreeMergeLandedFailureAcknowledgement struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptID string `json:"receipt_id"`
ReceiptStatus WorktreeMergeStatus `json:"receipt_status"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
ReceiptTargetSHA string `json:"receipt_target_sha"`
ReceiptLandingSHA string `json:"receipt_landing_sha,omitempty"`
CurrentTargetSHA string `json:"current_target_sha"`
CandidateSHA string `json:"candidate_sha"`
ClaimBaseSHA string `json:"claim_base_sha"`
CandidateWorktree string `json:"candidate_worktree"`
CandidateBranch string `json:"candidate_branch"`
Sources []WorktreeMergeSource `json:"sources"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeLandedFailureAcknowledgement is a separate, append-only acknowledgement for a historical merge receipt whose candidate is proved to be present in the current target but whose validation boundary never became terminal. The original merge receipt and Work Log remain untouched.
func AcknowledgeLandedMergeFailure ¶ added in v0.69.2
func AcknowledgeLandedMergeFailure(ctx context.Context, options WorktreeMergeLandedFailureAcknowledgementOptions) (WorktreeMergeLandedFailureAcknowledgement, error)
AcknowledgeLandedMergeFailure proves that a non-terminal failed receipt is already represented by the current remote target, then writes a distinct audited acknowledgement. It never rewrites the historical receipt or any Work Log record. A failed proof is always a refusal.
type WorktreeMergeLandedFailureAcknowledgementOptions ¶ added in v0.69.2
type WorktreeMergeLegacyValidationFailureIdentity ¶ added in v0.97.1
type WorktreeMergeLegacyValidationFailureIdentity struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ReceiptID string `json:"receipt_id"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
ReceiptTargetSHA string `json:"receipt_target_sha"`
CurrentTargetSHA string `json:"current_target_sha"`
Candidate WorktreeMergeCandidate `json:"candidate"`
ClaimBaseSHA string `json:"claim_base_sha"`
Sources []WorktreeMergeSource `json:"sources"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeLegacyValidationFailureIdentity records the only identity WB may derive for a legacy validation_failed receipt whose writer omitted the candidate SHA. The historical receipt remains immutable; every field here is corroborated from its registered candidate worktree, active claim, exact sources, and current remote-target observation.
type WorktreeMergeMissingCleanupAcknowledgement ¶ added in v0.97.4
type WorktreeMergeMissingCleanupAcknowledgement struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ReceiptID string `json:"receipt_id"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
LandingSHA string `json:"landing_sha"`
CurrentTargetSHA string `json:"current_target_sha"`
Assets []worktrees.TerminalWorkLogExpectation `json:"absent_assets"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeMissingCleanupAcknowledgement records the narrow legacy case where a landed receipt's exact worktrees and branches were already removed, but the historical cleanup did not retain terminal Work Log evidence.
func AcknowledgeMissingWorktreeMergeCleanup ¶ added in v0.97.4
func AcknowledgeMissingWorktreeMergeCleanup(ctx context.Context, options WorktreeMergeMissingCleanupAcknowledgementOptions) (WorktreeMergeMissingCleanupAcknowledgement, error)
AcknowledgeMissingWorktreeMergeCleanup records independently reproducible evidence for legacy cleanup which removed every exact asset but lost one or more terminal Work Logs. It never creates replacement Work Log evidence.
type WorktreeMergeMissingCleanupAcknowledgementOptions ¶ added in v0.97.4
type WorktreeMergePhase ¶ added in v0.66.0
type WorktreeMergePhase string
const ( WorktreeMergePhasePrepare WorktreeMergePhase = "prepare" WorktreeMergePhaseLand WorktreeMergePhase = "land" WorktreeMergePhaseRevert WorktreeMergePhase = "revert" )
type WorktreeMergePrepareOptions ¶ added in v0.66.0
type WorktreeMergePrepareOptions struct {
ProjectsRoot string
Sources []string
Target string
Model string
AgentRuntime string
AgentID string
Initiator string
CLI string
Provider string
Timeout time.Duration
Retry int
// PrepareTimeout bounds one prepare invocation. Zero leaves preparation
// unbounded apart from the existing command timeout.
PrepareTimeout time.Duration
// CheckTimeout bounds one logical candidate or baseline validation check.
// Zero retains the existing per-command behavior.
CheckTimeout time.Duration
// ShardAttemptTimeout bounds one process-isolated Go test shard attempt.
// Zero retains the existing --timeout behavior for shard attempts.
ShardAttemptTimeout time.Duration
Progress progress.Reporter
ProgressRequested bool
// RebatchReceipt is an immutable, still-unlanded prepared receipt whose
// sources are being replaced additively and/or extended in this prepare.
RebatchReceipt string
}
type WorktreeMergePreparedRebatch ¶ added in v0.71.0
type WorktreeMergePreparedRebatch struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptID string `json:"receipt_id"`
ReceiptSHA256 string `json:"receipt_sha256"`
ReceiptStatus WorktreeMergeStatus `json:"receipt_status"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
ReceiptTargetSHA string `json:"receipt_target_sha"`
CurrentTargetSHA string `json:"current_target_sha"`
OriginalCandidate WorktreeMergeCandidate `json:"original_candidate"`
OriginalSources []WorktreeMergeSource `json:"original_sources"`
ReplacementReceiptPath string `json:"replacement_receipt_path"`
Replacement WorktreeMergeCandidate `json:"replacement"`
Sources []WorktreeMergeSource `json:"sources"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergePreparedRebatch is an append-only link from one unlanded prepared receipt to a newly prepared candidate with an additive source set. It deliberately retains the original candidate and its exact receipt digest; neither historical record is changed to make room for a later source.
type WorktreeMergePublishedCandidateAdoption ¶ added in v0.95.2
type WorktreeMergePublishedCandidateAdoption struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ReceiptID string `json:"receipt_id"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
Candidate WorktreeMergeCandidate `json:"candidate"`
PullRequest string `json:"pull_request"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergePublishedCandidateAdoption records remote publication that completed outside WB after prepare persisted but before it could record the PR. It is deliberately separate from the immutable merge receipt.
func AdoptPublishedWorktreeMergeCandidate ¶ added in v0.95.2
func AdoptPublishedWorktreeMergeCandidate(ctx context.Context, options WorktreeMergePublishedCandidateAdoptionOptions) (WorktreeMergePublishedCandidateAdoption, error)
type WorktreeMergePublishedCandidateAdoptionOptions ¶ added in v0.95.2
type WorktreeMergePublishedForwardRepair ¶ added in v0.80.2
type WorktreeMergePublishedForwardRepair struct {
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ImmutableClaimSHA256 string `json:"immutable_claim_sha256"`
SupersessionPath string `json:"supersession_path"`
SupersessionSHA256 string `json:"supersession_sha256"`
CurrentTargetSHA string `json:"current_target_sha"`
Sources []WorktreeMergeSource `json:"sources"`
RequiredRoots []WorktreeMergeValidationFailureSealRoot `json:"required_roots"`
Candidate WorktreeMergeCandidate `json:"candidate"`
Actor string `json:"actor"`
Reason string `json:"reason"`
}
WorktreeMergePublishedForwardRepair is a deliberately unprepared candidate for correcting one historical self-supersession. It has no merge receipt: the later correction is the only append-only transition that can consume it.
func PreparePublishedValidationFailureForwardRepair ¶ added in v0.80.2
func PreparePublishedValidationFailureForwardRepair(ctx context.Context, options WorktreeMergePublishedForwardRepairOptions) (result WorktreeMergePublishedForwardRepair, retErr error)
PreparePublishedValidationFailureForwardRepair is the explicit cycle breaker for an already-published historical self-supersession. Ordinary prepare stays fail-closed. This path writes no historical artifact and creates no merge receipt; on apply it creates only one new WB-managed clean candidate whose DAG contains every immutable historical root and every pinned current source.
type WorktreeMergePublishedForwardRepairOptions ¶ added in v0.80.2
type WorktreeMergePublishedForwardRepairOptions struct {
ProjectsRoot, Receipt, ExpectedReceiptSHA256, ExpectedImmutableClaimSHA256 string
ExpectedSupersessionSHA256, ExpectedCurrentTargetSHA string
Sources, ExpectedSourceSHAs []string
Apply bool
Actor, Reason string
Model, AgentRuntime, AgentID, Initiator, CLI, Provider string
SessionRequired bool
Timeout time.Duration
Retry int
}
WorktreeMergePublishedForwardRepairOptions pins every mutable historical input needed to create a distinct candidate for one known self-supersession. ExpectedSourceSHAs are positional with Sources, so a caller cannot silently replace a requested current repair source with another clean worktree.
func (WorktreeMergePublishedForwardRepairOptions) RepairTask ¶ added in v0.80.2
func (options WorktreeMergePublishedForwardRepairOptions) RepairTask() string
RepairTask is deterministic solely from caller-pinned immutable evidence, allowing apply retries to resume the same WB-managed candidate without guessing a branch from mutable filesystem state.
type WorktreeMergePushGateReceipt ¶ added in v0.66.0
type WorktreeMergeRebaseReceipt ¶ added in v0.66.0
type WorktreeMergeReceipt ¶ added in v0.66.0
type WorktreeMergeReceipt struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Lane string `json:"lane"`
Phase WorktreeMergePhase `json:"phase"`
Status WorktreeMergeStatus `json:"status"`
Repository string `json:"repository"`
Target string `json:"target"`
TargetSHA string `json:"target_sha"`
Sources []WorktreeMergeSource `json:"sources"`
Candidate WorktreeMergeCandidate `json:"candidate"`
Rebase *WorktreeMergeRebaseReceipt `json:"rebase,omitempty"`
RevertOf *WorktreeMergeRevertReceipt `json:"revert_of,omitempty"`
Route WorktreeMergeRouteDecision `json:"route,omitempty"`
PullRequest string `json:"pull_request,omitempty"`
PublishedCandidateSHA string `json:"published_candidate_sha,omitempty"`
PreviousTargetSHA string `json:"previous_target_sha,omitempty"`
LandingSHA string `json:"landing_sha,omitempty"`
CanonicalSync string `json:"canonical_sync,omitempty"`
Validation quality.VerificationReport `json:"validation,omitempty"`
BaselineValidation quality.VerificationReport `json:"baseline_validation,omitempty"`
ValidationIdentity *WorktreeMergeValidationIdentity `json:"validation_identity,omitempty"`
ValidationTimeouts *WorktreeMergeValidationTimeouts `json:"validation_timeouts,omitempty"`
Checks PullRequestWaitResult `json:"checks,omitempty"`
PushGate *WorktreeMergePushGateReceipt `json:"push_gate,omitempty"`
ForwardRepairs []WorktreeMergeForwardRepairReceipt `json:"forward_repairs,omitempty"`
Cleanup bool `json:"cleanup_requested"`
OnFailure string `json:"on_failure,omitempty"`
CleanupReports []string `json:"cleanup_reports,omitempty"`
CleanedTasks []string `json:"cleaned_tasks,omitempty"`
SourceRefreshes []WorktreeMergeSourceRefresh `json:"source_refreshes,omitempty"`
// RebatchOf binds this candidate to an immutable prepared receipt whose
// source set was safely expanded. The old receipt is never rewritten.
RebatchOf string `json:"rebatch_of,omitempty"`
RebatchedCandidates []WorktreeMergeCandidate `json:"rebatched_candidates,omitempty"`
Failure string `json:"failure,omitempty"`
ResumeArgs []string `json:"resume_args,omitempty"`
ReceiptPath string `json:"receipt_path"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
func LandWorktreeMerge ¶ added in v0.66.0
func LandWorktreeMerge(ctx context.Context, options WorktreeMergeLandOptions) (WorktreeMergeReceipt, error)
LandWorktreeMerge resumes a prepared receipt from its first incomplete boundary. It never reconstructs identity from a branch name and never force-pushes either the candidate or target branch.
func PrepareWorktreeMerge ¶ added in v0.66.0
func PrepareWorktreeMerge(ctx context.Context, options WorktreeMergePrepareOptions) (WorktreeMergeReceipt, error)
func PrepareWorktreeMergeRevert ¶ added in v0.66.0
func PrepareWorktreeMergeRevert(ctx context.Context, projectsRoot, input string, timeout time.Duration, retry int) (WorktreeMergeReceipt, error)
PrepareWorktreeMergeRevert creates a fresh forward candidate which applies the inverse landing tree delta onto today's remote target. It never resets or force-pushes shared history.
func ResumeWorktreeMerge ¶ added in v0.66.0
func ResumeWorktreeMerge(ctx context.Context, options WorktreeMergeLandOptions) (WorktreeMergeReceipt, error)
func RunWorktreeMerge ¶ added in v0.66.0
func RunWorktreeMerge(ctx context.Context, prepare WorktreeMergePrepareOptions, land WorktreeMergeLandOptions) (WorktreeMergeReceipt, error)
type WorktreeMergeReceiptCollisionAcknowledgement ¶ added in v0.80.2
type WorktreeMergeReceiptCollisionAcknowledgement struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ImmutableClaimSHA256 string `json:"immutable_claim_sha256"`
ReceiptID string `json:"receipt_id"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
ExpectedTargetSHA string `json:"expected_target_sha"`
ExpectedCandidateSHA string `json:"expected_candidate_sha"`
ExpectedCurrentSourceSHA string `json:"expected_current_source_sha"`
ExpectedHistoricalRefreshSourceSHA string `json:"expected_historical_refresh_source_sha"`
ClaimBaseSHA string `json:"claim_base_sha"`
Candidate WorktreeMergeCandidate `json:"candidate"`
CurrentSources []WorktreeMergeSource `json:"current_sources"`
HistoricalRefreshSources []WorktreeMergeSource `json:"historical_refresh_sources"`
HistoricalValidationFailedOperatorAssertion bool `json:"historical_validation_failed_operator_assertion"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeReceiptCollisionAcknowledgement is the narrowly scoped, append-only recovery record for a receipt that was historically rewritten by the pre-guard prepare collision. Historical validation_failed is an operator assertion here: no byte digest of the pre-mutation receipt exists.
func AcknowledgeWorktreeMergeReceiptCollision ¶ added in v0.80.2
func AcknowledgeWorktreeMergeReceiptCollision(ctx context.Context, options WorktreeMergeReceiptCollisionAcknowledgementOptions) (WorktreeMergeReceiptCollisionAcknowledgement, error)
AcknowledgeWorktreeMergeReceiptCollision records the one audited recovery path for a known historical receipt collision. It never infers the incident: the caller must pin every observed digest and revision before --apply can write the separate acknowledgement.
type WorktreeMergeReceiptCollisionAcknowledgementOptions ¶ added in v0.80.2
type WorktreeMergeRevertReceipt ¶ added in v0.66.0
type WorktreeMergeRoute ¶ added in v0.66.0
type WorktreeMergeRoute string
const ( WorktreeMergeRouteAuto WorktreeMergeRoute = "auto" WorktreeMergeRouteDirect WorktreeMergeRoute = "direct" WorktreeMergeRoutePullRequest WorktreeMergeRoute = "pr" WorktreeMergeRouteUnsupported WorktreeMergeRoute = "unsupported" )
type WorktreeMergeRouteDecision ¶ added in v0.66.0
type WorktreeMergeRouteDecision struct {
Requested WorktreeMergeRoute `json:"requested"`
Route WorktreeMergeRoute `json:"route"`
Reason string `json:"reason"`
}
func ResolveWorktreeMergeRoute ¶ added in v0.66.0
func ResolveWorktreeMergeRoute(ctx context.Context, repository, target string, requested WorktreeMergeRoute) (WorktreeMergeRouteDecision, error)
type WorktreeMergeSelfSupersessionCorrection ¶ added in v0.80.2
type WorktreeMergeSelfSupersessionCorrection struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
CorrectionPath string `json:"correction_path"`
ReceiptPath string `json:"receipt_path"`
ReceiptSHA256 string `json:"receipt_sha256"`
ImmutableClaimSHA256 string `json:"immutable_claim_sha256"`
SupersessionPath string `json:"supersession_path"`
SupersessionSHA256 string `json:"supersession_sha256"`
SupersessionID string `json:"supersession_id"`
OriginalCandidate WorktreeMergeCandidate `json:"original_candidate"`
OriginalClaimBaseSHA string `json:"original_claim_base_sha"`
CorrectedReplacement WorktreeMergeCandidate `json:"corrected_replacement"`
ReplacementClaimBaseSHA string `json:"replacement_claim_base_sha"`
CurrentTargetSHA string `json:"current_target_sha"`
Sources []WorktreeMergeSource `json:"sources"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeSelfSupersessionCorrection is the only repair for a historical supersession acknowledgement that incorrectly named the failed candidate as its own replacement. It is append-only and binds both the exact corrupt ack bytes and one distinct, fully revalidated replacement candidate.
func CorrectValidationFailedSelfSupersession ¶ added in v0.80.2
func CorrectValidationFailedSelfSupersession(ctx context.Context, options WorktreeMergeSelfSupersessionCorrectionOptions) (WorktreeMergeSelfSupersessionCorrection, error)
CorrectValidationFailedSelfSupersession repairs only a pre-guard self-supersession. It never replaces that acknowledgement: it records one separate correction whose identity pins the exact existing acknowledgement, receipt, immutable claim, and distinct replacement evidence.
type WorktreeMergeSelfSupersessionCorrectionOptions ¶ added in v0.80.2
type WorktreeMergeSource ¶ added in v0.66.0
type WorktreeMergeSourceRefresh ¶ added in v0.66.0
type WorktreeMergeSourceRefresh struct {
RecordedAt time.Time `json:"recorded_at"`
Sources []WorktreeMergeSource `json:"sources"`
}
type WorktreeMergeStatus ¶ added in v0.66.0
type WorktreeMergeStatus string
const ( WorktreeMergePreparing WorktreeMergeStatus = "preparing" WorktreeMergePrepared WorktreeMergeStatus = "prepared" WorktreeMergeConflict WorktreeMergeStatus = "conflict" WorktreeMergeValidationFailed WorktreeMergeStatus = "validation_failed" // WorktreeMergePublished is an intentional non-terminal handoff point: the // exact validated candidate is remotely published in an open pull request, // but WB has not observed checks or attempted a merge. A later ordinary // resume continues the landing journey from this exact receipt. WorktreeMergePublished WorktreeMergeStatus = "published_merge_pending" WorktreeMergeChecksPending WorktreeMergeStatus = "checks_pending" WorktreeMergeChecksFailed WorktreeMergeStatus = "checks_failed" WorktreeMergeLanded WorktreeMergeStatus = "landed_cleanup_pending" WorktreeMergeCanonicalSyncBlocked WorktreeMergeStatus = "landed_canonical_sync_blocked" WorktreeMergePostTargetCIFailed WorktreeMergeStatus = "landed_post_target_ci_failed" WorktreeMergeComplete WorktreeMergeStatus = "complete" )
type WorktreeMergeStrandedLandingAcknowledgement ¶ added in v0.79.0
type WorktreeMergeStrandedLandingAcknowledgement struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptID string `json:"receipt_id"`
ReceiptSHA256 string `json:"receipt_sha256"`
ReceiptStatus WorktreeMergeStatus `json:"receipt_status"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
ReceiptTargetSHA string `json:"receipt_target_sha"`
CandidateSHA string `json:"candidate_sha"`
PullRequest string `json:"pull_request"`
// ProvedLandingSHA is GitHub's own server merge-result commit for
// PullRequest, discovered live by this acknowledgement. The historical
// receipt's own LandingSHA is deliberately left empty by this recovery
// path: the tool itself never observed the landing at the time, and this
// field records the later, separately audited proof instead.
ProvedLandingSHA string `json:"proved_landing_sha"`
CurrentTargetSHA string `json:"current_target_sha"`
Sources []WorktreeMergeSource `json:"sources"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeStrandedLandingAcknowledgement is a separate, append-only acknowledgement for a land/conflict receipt whose exact published pull request is proved MERGED, and whose merge commit and preserved candidate are both proved contained in the freshly fetched current remote target, using only GitHub's remote state. This receipt shape exists precisely because the candidate (and every receipted source) worktree is already gone -- typically because a resume's landing-result read failed on pure I/O after infrastructure cleanup raced ahead of it -- so no local git ancestry check against that worktree is possible. The historical merge receipt and every Work Log remain untouched; this acknowledgement only frees the merger lane for the next candidate.
func AcknowledgeStrandedPullRequestLanding ¶ added in v0.79.0
func AcknowledgeStrandedPullRequestLanding(ctx context.Context, options WorktreeMergeStrandedLandingAcknowledgementOptions) (WorktreeMergeStrandedLandingAcknowledgement, error)
AcknowledgeStrandedPullRequestLanding proves, using only GitHub's remote state, that a land/conflict receipt's exact published candidate merged and remains reachable from the current remote target, then records a separate audited acknowledgement so a fresh forward candidate can own the lane. It never reads or requires the candidate or any receipted source worktree: that infrastructure being gone is exactly the failure this recovers from. It never rewrites the historical receipt or any Work Log. This is a dry-run by default; --apply requires --actor and --reason.
type WorktreeMergeStrandedLandingAcknowledgementOptions ¶ added in v0.79.0
type WorktreeMergeStrandedLandingAcknowledgementOptions struct {
ProjectsRoot string
Receipt string
Apply bool
Actor string
Reason string
}
WorktreeMergeStrandedLandingAcknowledgementOptions configures AcknowledgeStrandedPullRequestLanding.
type WorktreeMergeValidationFailureSeal ¶ added in v0.70.0
type WorktreeMergeValidationFailureSeal struct {
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
ReceiptID string `json:"receipt_id"`
ReceiptSHA256 string `json:"receipt_sha256"`
Repository string `json:"repository"`
Target string `json:"target"`
CurrentTargetSHA string `json:"current_target_sha"`
TargetTreeSHA string `json:"target_tree_sha"`
RequiredRoots []WorktreeMergeValidationFailureSealRoot `json:"required_roots"`
Candidate WorktreeMergeCandidate `json:"candidate"`
Actor string `json:"actor"`
Reason string `json:"reason"`
}
WorktreeMergeValidationFailureSeal is the result of preparing a clean, target-tree-identical replacement candidate. It is not a supersession acknowledgement; the historical receipt remains active until the caller separately records one with supersede-validation-failed.
func PrepareValidationFailedWorktreeMergeSeal ¶ added in v0.70.0
func PrepareValidationFailedWorktreeMergeSeal(ctx context.Context, options WorktreeMergeValidationFailureSealOptions) (WorktreeMergeValidationFailureSeal, error)
PrepareValidationFailedWorktreeMergeSeal creates a WB-managed candidate at the freshly fetched target and, when necessary, adds only merge ancestry via Git's ours strategy. It refuses unless the candidate's final tree is exactly the fetched target tree and every approved immutable root is an ancestor. It never edits the historical merge receipt or any existing Work Log.
type WorktreeMergeValidationFailureSealOptions ¶ added in v0.70.0
type WorktreeMergeValidationFailureSealRoot ¶ added in v0.70.0
type WorktreeMergeValidationFailureSealRoot struct {
Kind string `json:"kind"`
SHA string `json:"sha"`
}
WorktreeMergeValidationFailureSealRoot names one immutable history root that a no-content recovery candidate must contain.
type WorktreeMergeValidationFailureSupersession ¶ added in v0.69.3
type WorktreeMergeValidationFailureSupersession struct {
SchemaVersion int `json:"schema_version"`
ID string `json:"id"`
Status string `json:"status"`
ReceiptPath string `json:"receipt_path"`
AcknowledgementPath string `json:"acknowledgement_path"`
ReceiptID string `json:"receipt_id"`
ReceiptSHA256 string `json:"receipt_sha256"`
ReceiptStatus WorktreeMergeStatus `json:"receipt_status"`
Lane string `json:"lane"`
Repository string `json:"repository"`
Target string `json:"target"`
ReceiptTargetSHA string `json:"receipt_target_sha"`
CurrentTargetSHA string `json:"current_target_sha"`
OriginalCandidate WorktreeMergeCandidate `json:"original_candidate"`
ObservedCandidateDescendantSHA string `json:"observed_candidate_descendant_sha,omitempty"`
OriginalClaimBaseSHA string `json:"original_claim_base_sha"`
Replacement WorktreeMergeCandidate `json:"replacement"`
ReplacementClaimBaseSHA string `json:"replacement_claim_base_sha"`
Sources []WorktreeMergeSource `json:"sources"`
Actor string `json:"actor"`
Reason string `json:"reason"`
RecordedAt time.Time `json:"recorded_at"`
}
WorktreeMergeValidationFailureSupersession is a separate, append-only transition for a failed prepare candidate that never landed. It binds the immutable failed receipt to one clean replacement candidate without changing either candidate's Work Log or the historical receipt.
func SupersedeValidationFailedWorktreeMerge ¶ added in v0.69.3
func SupersedeValidationFailedWorktreeMerge(ctx context.Context, options WorktreeMergeValidationFailureSupersessionOptions) (WorktreeMergeValidationFailureSupersession, error)
SupersedeValidationFailedWorktreeMerge proves that a clean replacement candidate contains every immutable root of an unlanded prepare failure. The failed candidate itself need not be an ancestor: it may have diverged after validation failed. This transition is deliberately narrower than the landed acknowledgement because it never asserts that the failed candidate landed.
type WorktreeMergeValidationFailureSupersessionOptions ¶ added in v0.69.3
type WorktreeMergeValidationIdentity ¶ added in v0.98.3
type WorktreeMergeValidationIdentity struct {
CandidateSHA string `json:"candidate_sha"`
TargetSHA string `json:"target_sha"`
SourceSHAs []string `json:"source_shas"`
QualityPolicySHA string `json:"quality_policy_sha"`
WBBuild string `json:"wb_build"`
WBExecutableSHA string `json:"wb_executable_sha"`
Validators map[string]string `json:"validators,omitempty"`
}
WorktreeMergeValidationIdentity binds a successful prepare validation to every cheap input that can make rerunning it produce a different result. Missing identity is deliberately treated as a cache miss for old receipts.
type WorktreeMergeValidationTimeouts ¶ added in v0.99.0
type WorktreeMergeValidationTimeouts struct {
Check time.Duration `json:"check_timeout,omitempty"`
ShardAttempt time.Duration `json:"shard_attempt_timeout,omitempty"`
}
WorktreeMergeValidationTimeouts retains explicit validation limits on a prepared candidate so a later land/resume repeats the same validation policy. The overall prepare deadline is intentionally not retained: it bounds one caller's operation rather than the candidate's validation contract.
Source Files
¶
- ciwait.go
- command.go
- engine.go
- fetch_memo.go
- github_observer.go
- github_vendored.go
- mechanical.go
- pr_land.go
- pr_land_keep.go
- process_status_unix.go
- types.go
- worktree_merge.go
- worktree_merge_ack.go
- worktree_merge_adopt_published.go
- worktree_merge_conflict_replacement.go
- worktree_merge_lane_claim.go
- worktree_merge_published_forward_repair.go
- worktree_merge_seal.go
- worktree_merge_stranded.go