Documentation
¶
Index ¶
- Constants
- Variables
- func ApplicableReviewResultRefs(task WorkTask) []string
- func ReviewResultRefAppliesTo(taskID, ref string) bool
- func ReworkTransitionAllowed(from, to string, task WorkTask) bool
- type AttachInput
- type Attachment
- type CreateWorkPlanInput
- type CreateWorkTaskInput
- type DependencySummary
- type DirtyScopeRetryIncrementInput
- type ExpandWorkTaskScopeInput
- type GetNextWorkTaskInput
- type GetNextWorkTaskResult
- type RequestReworkInput
- type ResumeWorkPlanInput
- type Service
- func (svc *Service) AttachClaim(ctx context.Context, input AttachInput) (Attachment, error)
- func (svc *Service) AttachContextPack(ctx context.Context, input AttachInput) (Attachment, error)
- func (svc *Service) AttachEvidence(ctx context.Context, input AttachInput) (Attachment, error)
- func (svc *Service) AttachKnowledgeCandidate(ctx context.Context, input AttachInput) (Attachment, error)
- func (svc *Service) AttachReviewResult(ctx context.Context, input AttachInput) (Attachment, error)
- func (svc *Service) AttachReworkRequest(ctx context.Context, input AttachInput) (Attachment, error)
- func (svc *Service) AttachVerifierResult(ctx context.Context, input AttachInput) (Attachment, error)
- func (svc *Service) BlockWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)
- func (svc *Service) CallWorkPlanTool(ctx context.Context, name string, arguments json.RawMessage) (any, error)
- func (svc *Service) ClaimWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)
- func (svc *Service) ClearReworkMarker(ctx context.Context, projectID string, taskID string) (WorkTask, error)
- func (svc *Service) CompleteWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)
- func (svc *Service) CreateWorkPlan(ctx context.Context, input CreateWorkPlanInput) (WorkPlan, error)
- func (svc *Service) CreateWorkTask(ctx context.Context, input CreateWorkTaskInput) (WorkTask, error)
- func (svc *Service) DeleteWorkPlanCascade(ctx context.Context, projectID, planID string) (WorkPlanDeleteCounts, error)
- func (svc *Service) ExpandWorkTaskScope(ctx context.Context, input ExpandWorkTaskScopeInput) (WorkTask, error)
- func (svc *Service) FailWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)
- func (svc *Service) GetNextWorkTask(ctx context.Context, input GetNextWorkTaskInput) (GetNextWorkTaskResult, error)
- func (svc *Service) GetWorkPlan(ctx context.Context, projectID, planID string) (WorkPlan, error)
- func (svc *Service) GetWorkPlansByIDs(ctx context.Context, projectID string, planIDs []string) ([]WorkPlan, error)
- func (svc *Service) GetWorkTask(ctx context.Context, projectID, taskID string) (WorkTask, error)
- func (svc *Service) IncrementDirtyScopeRetryCount(ctx context.Context, input DirtyScopeRetryIncrementInput) (WorkTask, error)
- func (svc *Service) ListBlockedWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)
- func (svc *Service) ListMineWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)
- func (svc *Service) ListOpenWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)
- func (svc *Service) ListWorkPlans(ctx context.Context, filter WorkPlanFilter) ([]WorkPlan, error)
- func (svc *Service) ListWorkTasks(ctx context.Context, filter WorkTaskFilter) ([]WorkTask, error)
- func (svc *Service) ListWorkTasksByPlanIDs(ctx context.Context, projectID string, planIDs []string) ([]WorkTask, error)
- func (svc *Service) ReassessDecompositionQuality(ctx context.Context, projectID, taskID string) (WorkTask, bool, error)
- func (svc *Service) ReleaseWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)
- func (svc *Service) RequestRework(ctx context.Context, input RequestReworkInput) (WorkTask, error)
- func (svc *Service) ResetWorkTaskRecovery(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)
- func (svc *Service) ResumeWorkPlan(ctx context.Context, input ResumeWorkPlanInput) (WorkPlan, error)
- func (svc *Service) SetStatusChangeHandler(handler WorkPlanStatusChangeHandler)
- func (svc *Service) StartWorkTask(ctx context.Context, input WorkTaskActionInput) (WorkTask, error)
- func (svc *Service) UpdateWorkPlanStatus(ctx context.Context, input UpdateWorkPlanStatusInput) (WorkPlan, error)
- func (svc *Service) UpdateWorkTask(ctx context.Context, task WorkTask) (WorkTask, error)
- func (svc *Service) UpdateWorkTaskStatus(ctx context.Context, input UpdateWorkTaskStatusInput) (WorkTask, error)
- type Store
- type UpdateWorkPlanStatusInput
- type UpdateWorkTaskStatusInput
- type WorkPlan
- type WorkPlanDeleteCounts
- type WorkPlanFilter
- type WorkPlanStatusChange
- type WorkPlanStatusChangeHandler
- type WorkTask
- type WorkTaskActionInput
- type WorkTaskFilter
Constants ¶
const ( WorkPlanStatusPlanned = "planned" WorkPlanStatusActive = "active" WorkPlanStatusBlocked = "blocked" WorkPlanStatusNeedsReview = "needs_review" WorkPlanStatusDone = "done" WorkPlanStatusFailed = "failed" WorkPlanStatusCancelled = "cancelled" WorkPlanStatusSuperseded = "superseded" )
const ( WorkPlanIsolationDedicatedWorktree = "dedicated_worktree" )
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" )
const ( DecompositionDraft = "draft" DecompositionReady = "ready" DecompositionTooBroad = "too_broad" DecompositionMissingEvidence = "missing_evidence" DecompositionMissingContext = "missing_context" DecompositionMissingVerification = "missing_verification" DecompositionMissingResume = "missing_resume" )
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.
const MaxResumeInstructionsLength = 16 * 1024
MaxResumeInstructionsLength is kept for legacy tests and stored-value compatibility. New resume instruction validation is intentionally uncapped.
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.
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 ¶
var ErrInvalidInput = errors.New("invalid input")
Functions ¶
func ApplicableReviewResultRefs ¶ added in v0.3.0
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
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
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 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 DirtyScopeRetryIncrementInput ¶ added in v0.3.1
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 Service ¶
type Service struct {
// contains filtered or unexported fields
}
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 (*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 (*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 (*Service) CreateWorkPlan ¶
func (*Service) CreateWorkTask ¶
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 (*Service) FailWorkTask ¶
func (*Service) GetNextWorkTask ¶
func (svc *Service) GetNextWorkTask(ctx context.Context, input GetNextWorkTaskInput) (GetNextWorkTaskResult, error)
func (*Service) GetWorkPlan ¶
func (*Service) GetWorkPlansByIDs ¶ added in v0.3.0
func (*Service) GetWorkTask ¶
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 (*Service) ListMineWorkTasks ¶
func (*Service) ListOpenWorkTasks ¶
func (*Service) ListWorkPlans ¶
func (*Service) ListWorkTasks ¶ added in v0.3.0
func (*Service) ListWorkTasksByPlanIDs ¶ added in v0.3.0
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 (*Service) RequestRework ¶ added in v0.3.1
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 (*Service) SetStatusChangeHandler ¶ added in v0.2.1
func (svc *Service) SetStatusChangeHandler(handler WorkPlanStatusChangeHandler)
func (*Service) StartWorkTask ¶
func (*Service) UpdateWorkPlanStatus ¶
func (*Service) UpdateWorkTask ¶ added in v0.2.5
func (*Service) UpdateWorkTaskStatus ¶
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
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 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"`
}