Documentation
¶
Overview ¶
Package worktreeend closes one task's worktrees: the verb every lane contract already tells an agent to finish with.
It exists because "the agent is done" had no sanctioned expression. An agent that finished either left its checkout for a later sweep — the residue `wb worktree gc` has to clean up — or hand-rolled `git worktree remove`, which loses the claim, the Work Log seal and any uncommitted work in one step. `wb worktree end` is the one verb that does all three correctly.
It owns no new mechanics. Removal is the existing cleanup transaction, the claim release is the existing remote-claim path, and the closing note is the existing Work Log prompt journal. What this package adds is the order, the refusal, and the guarantee that uncommitted work is captured *before* anything is removed.
Implements: dependency-streams#req:sessions-and-tasks-have-explicit-ends, dependency-streams#req:merge-refuses-a-linked-worktree (its end-of-task half).
Index ¶
Constants ¶
const RefusalLiveLink = "live-link"
RefusalLiveLink is the one condition that stops a task from ending: a worktree still building against an unpublished library working tree.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Capture ¶
type Capture interface {
// DirtyPaths lists uncommitted paths, tracked and untracked.
DirtyPaths(ctx context.Context, worktree string) ([]string, error)
// Preserve captures the uncommitted work and returns a reference the
// operator can recover it from. It must not depend on the worktree
// surviving: the whole point is that removal follows.
Preserve(ctx context.Context, worktree, message string) (ref string, err error)
}
Capture preserves uncommitted work before anything is removed.
type Engine ¶
type Engine struct {
ProjectsRoot string
Inventory Inventory
Links LinkGuard
Capture Capture
Notes Notes
Retirer Retirer
Claims Claims
Now func() time.Time
}
Engine performs `wb worktree end` against injected ports.
func (*Engine) End ¶
End closes a task.
The order is the contract:
- refuse while any worktree holds a live local link — landing or discarding a checkout that builds against an unpublished working tree is the one thing end must never do silently;
- capture uncommitted work and print where it went, BEFORE any removal;
- seal the closing note into the Work Log;
- retire each worktree through the existing cleanup transaction;
- release the fleet-wide claim, but only once every worktree is gone.
A dirty worktree is not a refusal. Refusing one would leave the agent with exactly the choice this verb exists to remove: hand-roll the removal, or leave residue. Capturing first makes retiring it safe.
type Inventory ¶
type Inventory interface {
Worktrees(ctx context.Context, projectsRoot, task, repository string) ([]Worktree, error)
}
Inventory lists the task's worktrees.
type LinkGuard ¶
type LinkGuard interface {
// LiveLinks returns a human-readable reason per live link, and the
// command that clears each. An empty result means the worktree is free
// to be retired.
LiveLinks(worktree string) (reasons []string, sanctioned []string, err error)
}
LinkGuard answers whether a worktree still holds a live local link.
type MemberResult ¶
type MemberResult struct {
Repository string `json:"repository"`
Worktree string `json:"worktree"`
// Dirty lists the uncommitted paths found before anything was removed.
Dirty []string `json:"dirty,omitempty"`
// CaptureRef is where the uncommitted work was preserved. It is printed
// so the operator can recover it; a capture nobody can find is not a
// capture.
CaptureRef string `json:"capture_ref,omitempty"`
NotePath string `json:"note_path,omitempty"`
Removed bool `json:"removed"`
Action string `json:"action"`
Detail string `json:"detail,omitempty"`
}
MemberResult is one worktree's retirement.
type Options ¶
type Options struct {
Task string
// Repository narrows a coordinated task to one owner/repository.
Repository string
// Note is recorded in the Work Log as the task's closing statement.
Note string
// Apply performs the retirement. Without it nothing is changed and the
// report says exactly what would happen — including which worktrees carry
// uncommitted work that would be captured.
Apply bool
// KeepCapture stops the capture from being taken. It is not a bypass of
// anything: it is for a caller that has already preserved the work and
// does not want a second copy.
KeepCapture bool
}
Options is one `wb worktree end` invocation.
type Result ¶
type Result struct {
Task string `json:"task"`
Applied bool `json:"applied"`
Members []MemberResult `json:"members"`
ClaimOutcome string `json:"claim_outcome,omitempty"`
Errors []string `json:"errors,omitempty"`
}
Result is the whole invocation's report.