projectworkplan

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	WorkPlanStatusPlanned     = "planned"
	WorkPlanStatusActive      = "active"
	WorkPlanStatusBlocked     = "blocked"
	WorkPlanStatusNeedsReview = "needs_review"
	WorkPlanStatusDone        = "done"
	WorkPlanStatusFailed      = "failed"
	WorkPlanStatusCancelled   = "cancelled"
	WorkPlanStatusSuperseded  = "superseded"
)
View Source
const (
	WorkPlanIsolationShared            = "shared"
	WorkPlanIsolationDedicatedWorktree = "dedicated_worktree"
	WorkPlanIsolationUnavailable       = "unavailable"
)
View Source
const (
	WorkTaskStatusPlanned     = "planned"
	WorkTaskStatusReady       = "ready"
	WorkTaskStatusClaimed     = "claimed"
	WorkTaskStatusInProgress  = "in_progress"
	WorkTaskStatusBlocked     = "blocked"
	WorkTaskStatusNeedsReview = "needs_review"
	WorkTaskStatusVerifying   = "verifying"
	WorkTaskStatusDone        = "done"
	WorkTaskStatusFailed      = "failed"
	WorkTaskStatusCancelled   = "cancelled"
	WorkTaskStatusSuperseded  = "superseded"
)
View Source
const (
	DecompositionDraft               = "draft"
	DecompositionReady               = "ready"
	DecompositionTooBroad            = "too_broad"
	DecompositionMissingEvidence     = "missing_evidence"
	DecompositionMissingContext      = "missing_context"
	DecompositionMissingVerification = "missing_verification"
	DecompositionMissingResume       = "missing_resume"
)
View Source
const AttachmentKindReworkRequest = "rework_request_ref"

AttachmentKindReworkRequest is the attachment kind for a reviewer-requested rework marker. It is handled by a dedicated arm in addAttachmentRef that sets WorkTask.ReworkRequestedRef and transitions the task to needs_review.

View Source
const MaxResumeInstructionsLength = 16 * 1024

MaxResumeInstructionsLength is kept for legacy tests and stored-value compatibility. New resume instruction validation is intentionally uncapped.

View Source
const ReworkBudgetExhaustedOutcome = "rework_budget_exhausted"

ReworkBudgetExhaustedOutcome is the task outcome set when a task exhausts its rework budget (Phase 3, R5/R6). It is distinct from WorkPlanFailedOutcome so dashboards can distinguish rework exhaustion from a genuine work-plan failure, and so isTerminalReplacementFailure can partition it from the fatal-retry budget.

View Source
const ReworkRequestRefPrefix = "rework_request_"

ReworkRequestRefPrefix is the ref prefix for rework markers attached via the rework_request_ref attachment kind. A marker ref has the shape "rework_request_<taskID>_<nonce>". It lives on WorkTask.ReworkRequestedRef, NOT on ReviewResultRefs — see .ai/tasks/review-rework-loop-audit-and-fix-plan.md R8: reviewResultRefIsPassing treats any non-_failed ref as a passing approval, so a rework marker on ReviewResultRefs would auto-closeout the task.

Variables

View Source
var ErrInvalidInput = errors.New("invalid input")

Functions

func ApplicableReviewResultRefs added in v0.3.0

func ApplicableReviewResultRefs(task WorkTask) []string

ApplicableReviewResultRefs returns the task review result refs that may satisfy this task's own review gates per ReviewResultRefAppliesTo.

func ReviewResultRefAppliesTo added in v0.3.0

func ReviewResultRefAppliesTo(taskID, ref string) bool

ReviewResultRefAppliesTo reports whether a review result ref may satisfy the review gates of the task with the given ID. A ref that embeds a concrete generated task ID ("review_result_work_task_<hex>_...") applies only to that task; the same ref copied onto a different task is upstream pollution and must neither satisfy review gates nor block completion. Every other ref shape stays applicable so agents keep flexibility in how reviewers label their results.

func ReworkTransitionAllowed added in v0.3.1

func ReworkTransitionAllowed(from, to string, task WorkTask) bool

ReworkTransitionAllowed is the exported wrapper for orchestrator and test use. It reports whether the (from -> to) transition is permitted given the task's rework-marker state: base-table transitions are always allowed, and the rework-guarded transitions (verifying -> in_progress, needs_review -> in_progress) are allowed only when the task carries a fresh rework marker.

Types

type AttachInput

type AttachInput struct {
	ProjectID       string `json:"project_id,omitempty"`
	TaskID          string `json:"task_id"`
	Ref             string `json:"ref"`
	AttachedByRunID string `json:"attached_by_run_id,omitempty"`
	TraceID         string `json:"trace_id,omitempty"`
	Note            string `json:"note,omitempty"`
}

type Attachment

type Attachment struct {
	ID              string    `json:"id"`
	ProjectID       string    `json:"project_id"`
	PlanID          string    `json:"plan_id"`
	TaskID          string    `json:"task_id"`
	Kind            string    `json:"kind"`
	Ref             string    `json:"ref"`
	AttachedByRunID string    `json:"attached_by_run_id,omitempty"`
	TraceID         string    `json:"trace_id,omitempty"`
	Note            string    `json:"note,omitempty"`
	CreatedAt       time.Time `json:"created_at"`
}

type CreateWorkPlanInput

type CreateWorkPlanInput struct {
	ProjectID        string `json:"project_id,omitempty"`
	PlanRef          string `json:"plan_ref"`
	UserRequestRef   string `json:"user_request_ref,omitempty"`
	Title            string `json:"title"`
	GoalSummary      string `json:"goal_summary"`
	OwnerAgent       string `json:"owner_agent,omitempty"`
	CreatedByRunID   string `json:"created_by_run_id,omitempty"`
	ChainRunID       string `json:"chain_run_id,omitempty"`
	TraceID          string `json:"trace_id,omitempty"`
	ResumeSummary    string `json:"resume_summary,omitempty"`
	IsolationMode    string `json:"isolation_mode,omitempty"`
	ParallelGroupRef string `json:"parallel_group_ref,omitempty"`
	WorkspaceRef     string `json:"workspace_ref,omitempty"`
	GitBaseRef       string `json:"git_base_ref,omitempty"`
	GitBranchRef     string `json:"git_branch_ref,omitempty"`
	GitWorktreeRef   string `json:"git_worktree_ref,omitempty"`
}

type CreateWorkTaskInput

type CreateWorkTaskInput struct {
	ProjectID               string   `json:"project_id,omitempty"`
	PlanID                  string   `json:"plan_id"`
	TaskRef                 string   `json:"task_ref"`
	Title                   string   `json:"title"`
	Description             string   `json:"description,omitempty"`
	Status                  string   `json:"status,omitempty"`
	OwnerAgent              string   `json:"owner_agent,omitempty"`
	RunID                   string   `json:"run_id,omitempty"`
	TraceID                 string   `json:"trace_id,omitempty"`
	EvidenceNeeded          []string `json:"evidence_needed,omitempty"`
	ContextPackRefs         []string `json:"context_pack_refs,omitempty"`
	FilesToRead             []string `json:"files_to_read,omitempty"`
	FilesToEdit             []string `json:"files_to_edit,omitempty"`
	LikelyFilesAffected     []string `json:"likely_files_affected,omitempty"`
	DependencyTaskIDs       []string `json:"dependency_task_ids,omitempty"`
	VerificationRequirement string   `json:"verification_requirement"`
	GitOpsVerificationMode  string   `json:"gitops_verification_mode,omitempty"`
	ExpectedOutput          string   `json:"expected_output,omitempty"`
	FailureCriteria         string   `json:"failure_criteria,omitempty"`
	ReviewGate              string   `json:"review_gate,omitempty"`
	ResumeInstructions      string   `json:"resume_instructions,omitempty"`
	KnowledgeCandidateRefs  []string `json:"knowledge_candidate_refs,omitempty"`
	EvidenceRefs            []string `json:"evidence_refs,omitempty"`
	ClaimRefs               []string `json:"claim_refs,omitempty"`
	VerifierResultRefs      []string `json:"verifier_result_refs,omitempty"`
	ReviewResultRefs        []string `json:"review_result_refs,omitempty"`
	ReviewExemptReason      string   `json:"review_exempt_reason,omitempty"`
	ArtifactRefs            []string `json:"artifact_refs,omitempty"`
	AgentRunIDs             []string `json:"agent_run_ids,omitempty"`
	DecompositionQuality    string   `json:"decomposition_quality,omitempty"`
	AcceptanceCriteria      []string `json:"acceptance_criteria,omitempty"`
	StopConditions          []string `json:"stop_conditions,omitempty"`
	VerifierLadder          []string `json:"verifier_ladder,omitempty"`
	RegressionApplicability string   `json:"regression_test_applicability,omitempty"`
	DownstreamImpactRefs    []string `json:"downstream_impact_refs,omitempty"`
	OutputContract          string   `json:"output_contract,omitempty"`
}

type DependencySummary

type DependencySummary struct {
	TaskID string `json:"task_id"`
	Status string `json:"status"`
	Ready  bool   `json:"ready"`
}

type DirtyScopeRetryIncrementInput added in v0.3.1

type DirtyScopeRetryIncrementInput struct {
	ProjectID string
	TaskID    string
}

DirtyScopeRetryIncrementInput is the input to IncrementDirtyScopeRetryCount.

type ExpandWorkTaskScopeInput added in v0.2.4

type ExpandWorkTaskScopeInput struct {
	ProjectID          string   `json:"project_id,omitempty"`
	TaskID             string   `json:"task_id"`
	FilesToEdit        []string `json:"files_to_edit,omitempty"`
	ResumeInstructions string   `json:"resume_instructions,omitempty"`
	RunID              string   `json:"run_id,omitempty"`
	TraceID            string   `json:"trace_id,omitempty"`
}

type GetNextWorkTaskInput

type GetNextWorkTaskInput struct {
	ProjectID          string `json:"project_id,omitempty"`
	PlanID             string `json:"plan_id,omitempty"`
	OwnerAgent         string `json:"owner_agent,omitempty"`
	RunID              string `json:"run_id,omitempty"`
	TraceID            string `json:"trace_id,omitempty"`
	IncludeClaimedByMe bool   `json:"include_claimed_by_me,omitempty"`
}

type GetNextWorkTaskResult

type GetNextWorkTaskResult struct {
	Found                bool                `json:"found"`
	Task                 WorkTask            `json:"task,omitempty"`
	Plan                 WorkPlan            `json:"plan,omitempty"`
	DependencySummary    []DependencySummary `json:"dependency_summary,omitempty"`
	EvidenceRefs         []string            `json:"evidence_refs,omitempty"`
	ContextPackRefs      []string            `json:"context_pack_refs,omitempty"`
	ResumeInstructions   string              `json:"resume_instructions,omitempty"`
	RequiredVerification string              `json:"required_verification,omitempty"`
	SafeReason           string              `json:"safe_reason,omitempty"`
	OpenCount            int                 `json:"open_count"`
	BlockedCount         int                 `json:"blocked_count"`
	ClaimedCount         int                 `json:"claimed_count"`
	Reason               string              `json:"reason,omitempty"`
}

type RequestReworkInput added in v0.3.1

type RequestReworkInput struct {
	ProjectID        string `json:"project_id"`
	TaskID           string `json:"task_id"`
	RequestedByRunID string `json:"requested_by_run_id"`
	Reason           string `json:"reason,omitempty"`
	TraceID          string `json:"trace_id,omitempty"`
	Budget           int    `json:"budget,omitempty"`
}

RequestReworkInput is the input to Service.RequestRework, the first-class rework transition introduced in Phase 1 of the review-rework-loop fix. A reviewer run calls it to send an implementation task back for rework:

  • stamps ReworkRequestedRef / ReworkRequestedBy / ReworkReason,
  • increments ReworkCount,
  • transitions the task to needs_review (the orchestrator later moves it to in_progress when reclaiming it — see validateReworkTransition).

RequestedByRunID is the reviewer run; it must differ from the task's own ClaimedByRunID (independence gate, mirroring the review_result_ref gate at service.go attach()).

Budget (Phase 3) is the per-task rework ceiling. When >0 and the task's ReworkBudgetRemaining is 0 (unseeded), the task is seeded with this value. When ReworkBudgetRemaining reaches 0 after decrement, the task transitions to failed with outcome rework_budget_exhausted instead of needs_review. When Budget is 0 (e.g. tests that don't care about the ceiling), no budget enforcement is applied (Phase 1 behavior — unbounded rework).

type ResumeWorkPlanInput

type ResumeWorkPlanInput struct {
	ProjectID string `json:"project_id,omitempty"`
	PlanID    string `json:"plan_id"`
}

type Service

type Service struct {
	// contains filtered or unexported fields
}

func New

func New(store Store) *Service

func (*Service) AttachClaim

func (svc *Service) AttachClaim(ctx context.Context, input AttachInput) (Attachment, error)

func (*Service) AttachContextPack

func (svc *Service) AttachContextPack(ctx context.Context, input AttachInput) (Attachment, error)

func (*Service) AttachEvidence

func (svc *Service) AttachEvidence(ctx context.Context, input AttachInput) (Attachment, error)

func (*Service) AttachKnowledgeCandidate

func (svc *Service) AttachKnowledgeCandidate(ctx context.Context, input AttachInput) (Attachment, error)

func (*Service) AttachReviewResult

func (svc *Service) AttachReviewResult(ctx context.Context, input AttachInput) (Attachment, error)

func (*Service) AttachReworkRequest added in v0.3.1

func (svc *Service) AttachReworkRequest(ctx context.Context, input AttachInput) (Attachment, error)

AttachReworkRequest attaches a rework marker via the low-level attach path. It is the attachment-only counterpart to RequestRework: it stamps the marker ref + increments ReworkCount + transitions to needs_review, but does NOT set the ReworkRequestedBy/Reason audit fields (those are RequestRework-specific). The independence gate in attach() applies. Most callers should use RequestRework; this method exists for MCP/tooling that needs to record a rework marker from a raw ref without the full RequestRework ceremony.

func (*Service) AttachVerifierResult

func (svc *Service) AttachVerifierResult(ctx context.Context, input AttachInput) (Attachment, error)

func (*Service) BlockWorkTask

func (svc *Service) BlockWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)

func (*Service) CallWorkPlanTool

func (svc *Service) CallWorkPlanTool(ctx context.Context, name string, arguments json.RawMessage) (any, error)

CallWorkPlanTool adapts MCP tool calls onto the service-owned validation and state machine.

func (*Service) ClaimWorkTask

func (svc *Service) ClaimWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)

func (*Service) ClearReworkMarker added in v0.3.1

func (svc *Service) ClearReworkMarker(ctx context.Context, projectID string, taskID string) (WorkTask, error)

ClearReworkMarker clears the ReworkRequestedRef on a task without touching ReworkCount or ReworkBudgetRemaining. Called by the automation orchestrator after handleReworkRequest has queued the fresh implementation run — the marker has served its routing purpose and must be cleared so the fresh run's verifying phase does not re-trigger the rework branch (infinite loop).

func (*Service) CompleteWorkTask

func (svc *Service) CompleteWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)

func (*Service) CreateWorkPlan

func (svc *Service) CreateWorkPlan(ctx context.Context, input CreateWorkPlanInput) (WorkPlan, error)

func (*Service) CreateWorkTask

func (svc *Service) CreateWorkTask(ctx context.Context, input CreateWorkTaskInput) (WorkTask, error)

func (*Service) DeleteWorkPlanCascade added in v0.3.0

func (svc *Service) DeleteWorkPlanCascade(ctx context.Context, projectID, planID string) (WorkPlanDeleteCounts, error)

DeleteWorkPlanCascade permanently removes a work plan together with all of its tasks and every attachment on each task. The plan is flipped to a terminal status BEFORE children are removed so reconcilers stop touching it. Scoped by project. Idempotent: deleting an absent plan returns zero counts and nil. Used by the governed chain-run delete cascade. It does NOT remove automations (those are owned by the automation service; the caller handles them).

func (*Service) ExpandWorkTaskScope added in v0.2.4

func (svc *Service) ExpandWorkTaskScope(ctx context.Context, input ExpandWorkTaskScopeInput) (WorkTask, error)

func (*Service) FailWorkTask

func (svc *Service) FailWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)

func (*Service) GetNextWorkTask

func (svc *Service) GetNextWorkTask(ctx context.Context, input GetNextWorkTaskInput) (GetNextWorkTaskResult, error)

func (*Service) GetWorkPlan

func (svc *Service) GetWorkPlan(ctx context.Context, projectID, planID string) (WorkPlan, error)

func (*Service) GetWorkPlansByIDs added in v0.3.0

func (svc *Service) GetWorkPlansByIDs(ctx context.Context, projectID string, planIDs []string) ([]WorkPlan, error)

func (*Service) GetWorkTask

func (svc *Service) GetWorkTask(ctx context.Context, projectID, taskID string) (WorkTask, error)

func (*Service) IncrementDirtyScopeRetryCount added in v0.3.1

func (svc *Service) IncrementDirtyScopeRetryCount(ctx context.Context, input DirtyScopeRetryIncrementInput) (WorkTask, error)

IncrementDirtyScopeRetryCount atomically increments the F4 dirty-scope loop guard counter on a task (DirtyScopeRetryCount) and returns the updated task. It mirrors ExpandWorkTaskScope's lock→Get→mutate→Update pattern so the increment is safe under concurrent recovery passes. The caller (the automation layer's dirty-scope requeue chokepoint) reads the returned counter to decide whether to hard-block (counter > limit) or proceed with the normal expand/requeue. This counter is task-level and monotonic across run resets — unlike the run's AttemptCount, which blockTaskAfterOutOfScopeDirty- Paths resets to 0 on every requeue, defeating canRetryRun. The MASS-1929 25-claim incident looped precisely because no such persistent counter existed.

func (*Service) ListBlockedWorkTasks

func (svc *Service) ListBlockedWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)

func (*Service) ListMineWorkTasks

func (svc *Service) ListMineWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)

func (*Service) ListOpenWorkTasks

func (svc *Service) ListOpenWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)

func (*Service) ListWorkPlans

func (svc *Service) ListWorkPlans(ctx context.Context, filter WorkPlanFilter) ([]WorkPlan, error)

func (*Service) ListWorkTasks added in v0.3.0

func (svc *Service) ListWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)

func (*Service) ListWorkTasksByPlanIDs added in v0.3.0

func (svc *Service) ListWorkTasksByPlanIDs(ctx context.Context, projectID string, planIDs []string) ([]WorkTask, error)

func (*Service) ReassessDecompositionQuality added in v0.3.0

func (svc *Service) ReassessDecompositionQuality(ctx context.Context, projectID, taskID string) (WorkTask, bool, error)

ReassessDecompositionQuality re-evaluates a task's decomposition quality against its current metadata and promotes it if the assessment now returns "ready". This allows tasks that were initially "too_broad" or "missing_*" to become executable after evidence/context/files have been attached. Returns the updated task and whether the quality changed.

func (*Service) ReleaseWorkTask

func (svc *Service) ReleaseWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)

func (*Service) RequestRework added in v0.3.1

func (svc *Service) RequestRework(ctx context.Context, input RequestReworkInput) (WorkTask, error)

RequestRework is the first-class rework transition introduced in Phase 1 of the review-rework-loop fix (.ai/tasks/review-rework-loop-audit-and-fix-plan.md).

A reviewer run calls this to send an implementation task back for rework. It stamps the rework marker (ReworkRequestedRef / ReworkRequestedBy / ReworkReason), increments ReworkCount, and transitions the task to needs_review — the orchestrator later moves it to in_progress when reclaiming it (a transition only validateReworkTransition permits, because the marker is set).

The marker lives on ReworkRequestedRef, NOT on ReviewResultRefs, to avoid the R8 design trap: reviewResultRefIsPassing treats any non-_failed ref as a passing approval, so a rework marker on ReviewResultRefs would auto-closeout the task.

Guards:

  • RequestedByRunID is required and must differ from the task's own ClaimedByRunID (independence gate, mirroring the review_result_ref gate in attach() — the implementation run must not rework itself).
  • The task must be in a reviewable state (in_progress / verifying / needs_review). A rework request on a terminal task (done/failed/ cancelled/superseded) is rejected — no resurrection (I24/I25).

The rework-budget ceiling is enforced in Phase 3; Phase 1 accepts the request unconditionally on the budget front (ReworkCount is recorded but not yet checked against ReworkBudgetRemaining).

func (*Service) ResetWorkTaskRecovery added in v0.3.0

func (svc *Service) ResetWorkTaskRecovery(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)

ResetWorkTaskRecovery is the operator recovery path for a work task that hit the automation replacement-retry limit (automation_replacement_retry_limit_reached). It stamps a system-fix recovery marker (advancing UpdatedAt, which time-gates old terminal failures out of the replacement-retry counter) and moves the task back to ready so the orchestrator can queue a fresh run. Guarded: only callable on blocked/failed tasks — the operator attests the root cause is corrected.

func (*Service) ResumeWorkPlan

func (svc *Service) ResumeWorkPlan(ctx context.Context, input ResumeWorkPlanInput) (WorkPlan, error)

func (*Service) SetStatusChangeHandler added in v0.2.1

func (svc *Service) SetStatusChangeHandler(handler WorkPlanStatusChangeHandler)

func (*Service) StartWorkTask

func (svc *Service) StartWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)

func (*Service) UpdateWorkPlanStatus

func (svc *Service) UpdateWorkPlanStatus(ctx context.Context, input UpdateWorkPlanStatusInput) (WorkPlan, error)

func (*Service) UpdateWorkTask added in v0.2.5

func (svc *Service) UpdateWorkTask(ctx context.Context, task WorkTask) (WorkTask, error)

func (*Service) UpdateWorkTaskStatus

func (svc *Service) UpdateWorkTaskStatus(ctx context.Context, input UpdateWorkTaskStatusInput) (WorkTask, error)

type Store

type Store interface {
	CreateWorkPlan(context.Context, WorkPlan) (WorkPlan, error)
	GetWorkPlan(context.Context, string, string) (WorkPlan, error)
	GetWorkPlansByIDs(context.Context, string, []string) ([]WorkPlan, error)
	ListWorkPlans(context.Context, WorkPlanFilter) ([]WorkPlan, error)
	UpdateWorkPlan(context.Context, WorkPlan) (WorkPlan, error)
	CreateWorkTask(context.Context, WorkTask) (WorkTask, error)
	GetWorkTask(context.Context, string, string) (WorkTask, error)
	ListWorkTasksByPlanIDs(context.Context, string, []string) ([]WorkTask, error)
	ListWorkTasks(context.Context, WorkTaskFilter) ([]WorkTask, error)
	UpdateWorkTask(context.Context, WorkTask) (WorkTask, error)
	CreateAttachment(context.Context, Attachment) (Attachment, error)
	ListAttachments(context.Context, string, string) ([]Attachment, error)
	// DeleteWorkPlan permanently removes a work plan node. Scoped by project.
	// Idempotent: deleting an absent plan is a no-op.
	DeleteWorkPlan(context.Context, string, string) error
	// DeleteWorkTask permanently removes a work task node (not its plan).
	// Scoped by project. Idempotent.
	DeleteWorkTask(context.Context, string, string) error
	// DeleteAttachmentsForTask permanently removes every attachment node owned
	// by the given task, across all attachment kinds. Returns the count removed.
	// Scoped by project. Idempotent (0, nil) when none exist.
	DeleteAttachmentsForTask(context.Context, string, string) (int, error)
}

type UpdateWorkPlanStatusInput

type UpdateWorkPlanStatusInput struct {
	ProjectID      string `json:"project_id,omitempty"`
	PlanID         string `json:"plan_id"`
	Status         string `json:"status"`
	SafeNextAction string `json:"safe_next_action,omitempty"`
	ResumeSummary  string `json:"resume_summary,omitempty"`
	Outcome        string `json:"outcome,omitempty"`
	CurrentTaskID  string `json:"current_task_id,omitempty"`
	RunID          string `json:"run_id,omitempty"`
	TraceID        string `json:"trace_id,omitempty"`
}

type UpdateWorkTaskStatusInput

type UpdateWorkTaskStatusInput struct {
	WorkTaskActionInput
	Status string `json:"status"`
}

type WorkPlan

type WorkPlan struct {
	ID             string `json:"id"`
	ProjectID      string `json:"project_id"`
	PlanRef        string `json:"plan_ref"`
	UserRequestRef string `json:"user_request_ref,omitempty"`
	Title          string `json:"title"`
	GoalSummary    string `json:"goal_summary"`
	Status         string `json:"status"`
	OwnerAgent     string `json:"owner_agent,omitempty"`
	CreatedByRunID string `json:"created_by_run_id,omitempty"`
	// ChainRunID is the raw workflow chain run id that owns this plan, when the
	// plan was created by a chain compile. Unlike CreatedByRunID (which is a
	// synthetic workflow-safe token like "workflow-chain-run-<safeToken>"),
	// ChainRunID is the exact id returned by workflow_chains.list, so an
	// operator can match a plan to its chain run directly. Populated alongside
	// CreatedByRunID at compile time (T3.3). May be empty for plans created
	// outside a chain (manual plans, durable workflows). See
	// .ai/tasks/RUN_OBSERVABILITY_GAP.md §4 T3.3.
	ChainRunID       string    `json:"chain_run_id,omitempty"`
	TraceID          string    `json:"trace_id,omitempty"`
	CurrentTaskID    string    `json:"current_task_id,omitempty"`
	ResumeSummary    string    `json:"resume_summary,omitempty"`
	Outcome          string    `json:"outcome,omitempty"`
	IsolationMode    string    `json:"isolation_mode,omitempty"`
	ParallelGroupRef string    `json:"parallel_group_ref,omitempty"`
	WorkspaceRef     string    `json:"workspace_ref,omitempty"`
	GitBaseRef       string    `json:"git_base_ref,omitempty"`
	GitBranchRef     string    `json:"git_branch_ref,omitempty"`
	GitWorktreeRef   string    `json:"git_worktree_ref,omitempty"`
	CreatedAt        time.Time `json:"created_at"`
	UpdatedAt        time.Time `json:"updated_at"`
}

type WorkPlanDeleteCounts added in v0.3.0

type WorkPlanDeleteCounts struct {
	Tasks       int `json:"tasks"`
	Attachments int `json:"attachments"`
}

WorkPlanDeleteCounts tallies what a plan cascade delete removed.

type WorkPlanFilter

type WorkPlanFilter struct {
	ProjectID  string   `json:"project_id,omitempty"`
	PlanIDs    []string `json:"plan_ids,omitempty"`
	Status     string   `json:"status,omitempty"`
	OwnerAgent string   `json:"owner_agent,omitempty"`
	PageSize   int      `json:"page_size,omitempty"`
	PageToken  string   `json:"page_token,omitempty"`
}

type WorkPlanStatusChange added in v0.2.1

type WorkPlanStatusChange struct {
	ProjectID  string
	PlanID     string
	PlanRef    string
	OldStatus  string
	NewStatus  string
	OwnerAgent string
	ChangedAt  time.Time
}

type WorkPlanStatusChangeHandler added in v0.2.1

type WorkPlanStatusChangeHandler interface {
	HandleWorkPlanStatusChanged(context.Context, WorkPlanStatusChange) error
}

type WorkTask

type WorkTask struct {
	ID                      string   `json:"id"`
	ProjectID               string   `json:"project_id"`
	PlanID                  string   `json:"plan_id"`
	TaskRef                 string   `json:"task_ref"`
	Title                   string   `json:"title"`
	Description             string   `json:"description,omitempty"`
	Status                  string   `json:"status"`
	OwnerAgent              string   `json:"owner_agent,omitempty"`
	ClaimedByRunID          string   `json:"claimed_by_run_id,omitempty"`
	TraceID                 string   `json:"trace_id,omitempty"`
	EvidenceNeeded          []string `json:"evidence_needed,omitempty"`
	ContextPackRefs         []string `json:"context_pack_refs,omitempty"`
	FilesToRead             []string `json:"files_to_read,omitempty"`
	FilesToEdit             []string `json:"files_to_edit,omitempty"`
	LikelyFilesAffected     []string `json:"likely_files_affected,omitempty"`
	DependencyTaskIDs       []string `json:"dependency_task_ids,omitempty"`
	VerificationRequirement string   `json:"verification_requirement"`
	GitOpsVerificationMode  string   `json:"gitops_verification_mode,omitempty"`
	ExpectedOutput          string   `json:"expected_output,omitempty"`
	FailureCriteria         string   `json:"failure_criteria,omitempty"`
	ReviewGate              string   `json:"review_gate,omitempty"`
	Outcome                 string   `json:"outcome,omitempty"`
	ResumeInstructions      string   `json:"resume_instructions,omitempty"`
	BlockedReason           string   `json:"blocked_reason,omitempty"`
	// SafeNextAction is a persisted, queryable next-action hint for the task. It is
	// set by the automation service when a task is blocked (e.g. replacement-retry
	// limit reached) and by operator recovery (reset_recovery). Operators and the
	// orchestrator read it to decide what to do next without re-deriving it.
	SafeNextAction          string   `json:"safe_next_action,omitempty"`
	BlockedByTaskIDs        []string `json:"blocked_by_task_ids,omitempty"`
	KnowledgeCandidateRefs  []string `json:"knowledge_candidate_refs,omitempty"`
	EvidenceRefs            []string `json:"evidence_refs,omitempty"`
	ClaimRefs               []string `json:"claim_refs,omitempty"`
	VerifierResultRefs      []string `json:"verifier_result_refs,omitempty"`
	ReviewResultRefs        []string `json:"review_result_refs,omitempty"`
	ReviewExemptReason      string   `json:"review_exempt_reason,omitempty"`
	ArtifactRefs            []string `json:"artifact_refs,omitempty"`
	AgentRunIDs             []string `json:"agent_run_ids,omitempty"`
	DecompositionQuality    string   `json:"decomposition_quality"`
	AcceptanceCriteria      []string `json:"acceptance_criteria,omitempty"`
	StopConditions          []string `json:"stop_conditions,omitempty"`
	VerifierLadder          []string `json:"verifier_ladder,omitempty"`
	RegressionApplicability string   `json:"regression_test_applicability,omitempty"`
	DownstreamImpactRefs    []string `json:"downstream_impact_refs,omitempty"`
	OutputContract          string   `json:"output_contract,omitempty"`
	// Rework lifecycle (Phase 1 of the review-rework-loop fix). These fields
	// model reviewer-requested rework as a first-class signal, distinct from
	// approval refs (see .ai/tasks/review-rework-loop-audit-and-fix-plan.md R8:
	// a marker on ReviewResultRefs would be misread as a passing approval by
	// reviewResultRefIsPassing).
	//
	// ReworkRequestedRef holds the most recent rework marker ref
	// (rework_request_<taskID>_<nonce>). When non-empty, the guarded
	// rework transitions (verifying→in_progress, needs_review→in_progress)
	// become legal via validateReworkTransition. It is cleared once the
	// rework is consumed (the task is reclaimed for re-implementation).
	// ReworkCount is the lifetime number of rework requests accepted on this
	// task; it is the input to the rework-budget check (Phase 3).
	// ReworkBudgetRemaining is the remaining rework budget for this task
	// (seeded by the automation layer; 0 means unset/exhausted).
	// ReworkRequestedBy records the reviewer run that requested rework, for
	// auditability and the independence gate.
	// ReworkReason is the reviewer-supplied reason, surfaced to the
	// implementer on the next attempt.
	ReworkRequestedRef    string `json:"rework_requested_ref,omitempty"`
	ReworkCount           int    `json:"rework_count,omitempty"`
	ReworkBudgetRemaining int    `json:"rework_budget_remaining,omitempty"`
	ReworkRequestedBy     string `json:"rework_requested_by,omitempty"`
	ReworkReason          string `json:"rework_reason,omitempty"`
	// DirtyScopeRetryCount is the F4 dirty-scope loop guard counter: the number
	// of times this task has been requeued after a gitops_dirty_worktree_scope
	// failure. Unlike the run's AttemptCount (which blockTaskAfterOutOfScope-
	// DirtyPaths resets to 0 on every requeue, defeating canRetryRun), this
	// counter is task-level and monotonic across run resets, so it is the only
	// reliable signal for detecting the dirty-scope re-claim loop (the live
	// MASS-1929 25-claim incident). The automation layer increments it at the
	// dirty-scope requeue chokepoint and hard-blocks the task once it exceeds
	// Options.RecoveryMaxReplacementRunsPerTask. ResetWorkTaskRecovery clears it
	// so an operator reset gives the task a fresh budget.
	DirtyScopeRetryCount int       `json:"dirty_scope_retry_count,omitempty"`
	CreatedAt            time.Time `json:"created_at"`
	UpdatedAt            time.Time `json:"updated_at"`
	ClaimedAt            time.Time `json:"claimed_at,omitempty"`
	StartedAt            time.Time `json:"started_at,omitempty"`
	CompletedAt          time.Time `json:"completed_at,omitempty"`
}

type WorkTaskActionInput

type WorkTaskActionInput struct {
	ProjectID          string   `json:"project_id,omitempty"`
	TaskID             string   `json:"task_id"`
	OwnerAgent         string   `json:"owner_agent,omitempty"`
	RunID              string   `json:"run_id,omitempty"`
	TraceID            string   `json:"trace_id,omitempty"`
	Outcome            string   `json:"outcome,omitempty"`
	SafeNextAction     string   `json:"safe_next_action,omitempty"`
	BlockedReason      string   `json:"blocked_reason,omitempty"`
	BlockedByTaskIDs   []string `json:"blocked_by_task_ids,omitempty"`
	ContextPackRefs    []string `json:"context_pack_refs,omitempty"`
	EvidenceRefs       []string `json:"evidence_refs,omitempty"`
	ClaimRefs          []string `json:"claim_refs,omitempty"`
	KnowledgeRefs      []string `json:"knowledge_candidate_refs,omitempty"`
	ResumeInstructions string   `json:"resume_instructions,omitempty"`
	VerifierResultRefs []string `json:"verifier_result_refs,omitempty"`
	ReviewResultRefs   []string `json:"review_result_refs,omitempty"`
	ReviewExemptReason string   `json:"review_exempt_reason,omitempty"`
}

type WorkTaskFilter

type WorkTaskFilter struct {
	ProjectID      string   `json:"project_id,omitempty"`
	PlanID         string   `json:"plan_id,omitempty"`
	PlanIDs        []string `json:"plan_ids,omitempty"`
	Status         string   `json:"status,omitempty"`
	OwnerAgent     string   `json:"owner_agent,omitempty"`
	ClaimedByRunID string   `json:"claimed_by_run_id,omitempty"`
	PageSize       int      `json:"page_size,omitempty"`
	PageToken      string   `json:"page_token,omitempty"`
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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