summaryrefslogtreecommitdiff
path: root/docs/packages/task.md
diff options
context:
space:
mode:
authorClaudomator Agent <agent@claudomator>2026-03-11 00:43:41 +0000
committerClaudomator Agent <agent@claudomator>2026-03-11 00:43:41 +0000
commit23f9b65bf65b3d3677350a456e57294a4df810b9 (patch)
treebe6248759a39b4e451c73cfff8ddf6eb2d556269 /docs/packages/task.md
parent348a8894dc12cd5d4808a3eed0572aaf9e6b28cf (diff)
docs: add executor package documentation
Diffstat (limited to 'docs/packages/task.md')
-rw-r--r--docs/packages/task.md332
1 files changed, 332 insertions, 0 deletions
diff --git a/docs/packages/task.md b/docs/packages/task.md
new file mode 100644
index 0000000..3502f8a
--- /dev/null
+++ b/docs/packages/task.md
@@ -0,0 +1,332 @@
+# Package: `internal/task`
+
+## Overview
+
+The `task` package defines the core domain model for Claudomator. A **Task** represents a discrete unit of work to be executed by a Claude agent — described by natural-language instructions, optional budget and timeout constraints, retry policy, and scheduling metadata. Tasks are authored as YAML files and progress through a well-defined lifecycle from `PENDING` to a terminal state.
+
+---
+
+## Task Struct
+
+```go
+type Task struct {
+ ID string `yaml:"id"`
+ ParentTaskID string `yaml:"parent_task_id"`
+ Name string `yaml:"name"`
+ Description string `yaml:"description"`
+ Agent AgentConfig `yaml:"agent"`
+ Timeout Duration `yaml:"timeout"`
+ Retry RetryConfig `yaml:"retry"`
+ Priority Priority `yaml:"priority"`
+ Tags []string `yaml:"tags"`
+ DependsOn []string `yaml:"depends_on"`
+ State State `yaml:"-"`
+ RejectionComment string `yaml:"-"`
+ QuestionJSON string `yaml:"-"`
+ CreatedAt time.Time `yaml:"-"`
+ UpdatedAt time.Time `yaml:"-"`
+}
+```
+
+| Field | Type | Purpose | Default / Notes |
+|--------------------|---------------|----------------------------------------------------------------------|------------------------------------------|
+| `ID` | `string` | Unique identifier (UUID). | Auto-generated by `Parse` if empty. |
+| `ParentTaskID` | `string` | ID of the parent task; empty for top-level tasks. | Optional. |
+| `Name` | `string` | Human-readable name. **Required.** | Must be non-empty. |
+| `Description` | `string` | Longer explanation shown in the UI. | Optional. |
+| `Agent` | `AgentConfig` | Configuration passed to the Claude agent executor. | See [AgentConfig](#agentconfig-struct). |
+| `Timeout` | `Duration` | Maximum wall-clock time for a single execution attempt. | `0` means no limit. |
+| `Retry` | `RetryConfig` | Retry policy applied when a run fails. | See [RetryConfig](#retryconfig-struct). |
+| `Priority` | `Priority` | Scheduling priority: `high`, `normal`, or `low`. | Default: `normal`. |
+| `Tags` | `[]string` | Arbitrary labels for filtering and grouping. | Optional; defaults to `[]`. |
+| `DependsOn` | `[]string` | IDs of tasks that must reach `COMPLETED` before this one is queued. | Optional; defaults to `[]`. |
+| `State` | `State` | Current lifecycle state. Not read from YAML (`yaml:"-"`). | Set to `PENDING` by `Parse`. |
+| `RejectionComment` | `string` | Free-text comment left by a reviewer when rejecting a task. | Not in YAML; populated by storage layer. |
+| `QuestionJSON` | `string` | JSON-encoded question posted by the agent while `BLOCKED`. | Not in YAML; populated by storage layer. |
+| `CreatedAt` | `time.Time` | Timestamp set when the task is parsed. | Auto-set by `Parse`. |
+| `UpdatedAt` | `time.Time` | Timestamp updated on every state change. | Auto-set by `Parse`; updated by DB. |
+
+Fields tagged `yaml:"-"` are runtime-only and are never parsed from YAML task files.
+
+---
+
+## AgentConfig Struct
+
+```go
+type AgentConfig struct {
+ Type string `yaml:"type"`
+ Model string `yaml:"model"`
+ ContextFiles []string `yaml:"context_files"`
+ Instructions string `yaml:"instructions"`
+ ProjectDir string `yaml:"project_dir"`
+ MaxBudgetUSD float64 `yaml:"max_budget_usd"`
+ PermissionMode string `yaml:"permission_mode"`
+ AllowedTools []string `yaml:"allowed_tools"`
+ DisallowedTools []string `yaml:"disallowed_tools"`
+ SystemPromptAppend string `yaml:"system_prompt_append"`
+ AdditionalArgs []string `yaml:"additional_args"`
+ SkipPlanning bool `yaml:"skip_planning"`
+}
+```
+
+| Field | Type | Purpose |
+|----------------------|------------|---------------------------------------------------------------------------------------------------------------------------------|
+| `Type` | `string` | Agent type classifier. Cleared on retry by `ResetTaskForRetry` so the task can be re-classified. |
+| `Model` | `string` | Claude model ID (e.g. `"claude-sonnet-4-6"`). Cleared on retry alongside `Type`. |
+| `ContextFiles` | `[]string` | Paths to files pre-loaded as context for the agent. |
+| `Instructions` | `string` | Natural-language task instructions. **Required.** |
+| `ProjectDir` | `string` | Working directory the agent operates in. |
+| `MaxBudgetUSD` | `float64` | API spend cap in USD. `0` means no limit. Must be ≥ 0. |
+| `PermissionMode` | `string` | Claude permission mode. Valid values: `default`, `acceptEdits`, `bypassPermissions`, `plan`, `dontAsk`, `delegate`. |
+| `AllowedTools` | `[]string` | Explicit tool whitelist passed to the agent. |
+| `DisallowedTools` | `[]string` | Explicit tool blacklist passed to the agent. |
+| `SystemPromptAppend` | `string` | Text appended to the Claude system prompt. |
+| `AdditionalArgs` | `[]string` | Extra CLI arguments forwarded verbatim to the Claude executable. |
+| `SkipPlanning` | `bool` | When `true`, the agent skips the planning phase. |
+
+---
+
+## RetryConfig Struct
+
+```go
+type RetryConfig struct {
+ MaxAttempts int `yaml:"max_attempts"`
+ Backoff string `yaml:"backoff"` // "linear" or "exponential"
+}
+```
+
+| Field | Type | Purpose | Default |
+|---------------|----------|------------------------------------------------------------|-----------------|
+| `MaxAttempts` | `int` | Total number of attempts (first run + retries). Min: 1. | `1` |
+| `Backoff` | `string` | Wait strategy between retries: `linear` or `exponential`. | `"exponential"` |
+
+---
+
+## YAML Task File Format
+
+A task file may contain a single task or a batch (see next section). Every supported field is shown below with annotations.
+
+```yaml
+# Unique identifier. Omit to have Claudomator generate a UUID.
+id: "fix-login-bug"
+
+# Display name. Required.
+name: "Fix login redirect bug"
+
+# Optional longer description.
+description: "Users are redirected to /home instead of /dashboard after login."
+
+agent:
+ # Agent type for routing/classification. Optional; auto-assigned if blank.
+ type: "claude"
+
+ # Claude model ID. Optional; auto-assigned if blank.
+ model: "claude-sonnet-4-6"
+
+ # Task instructions passed to the agent. Required.
+ instructions: |
+ Fix the post-login redirect in src/auth/login.go so that users are
+ sent to /dashboard instead of /home. Add a regression test.
+
+ # Working directory for the agent process.
+ project_dir: "/workspace/myapp"
+
+ # Files loaded into the agent's context before execution starts.
+ context_files:
+ - "src/auth/login.go"
+ - "docs/adr/0003-auth.md"
+
+ # USD spending cap. 0 = no limit.
+ max_budget_usd: 1.00
+
+ # Claude permission mode.
+ # Values: default | acceptEdits | bypassPermissions | plan | dontAsk | delegate
+ permission_mode: "acceptEdits"
+
+ # Tool whitelist. Empty = all tools allowed.
+ allowed_tools:
+ - "Read"
+ - "Edit"
+ - "Bash"
+
+ # Tool blacklist.
+ disallowed_tools:
+ - "WebFetch"
+
+ # Appended to the agent's system prompt.
+ system_prompt_append: "Always write tests before implementation."
+
+ # Extra arguments forwarded verbatim to the Claude executable.
+ additional_args:
+ - "--verbose"
+
+ # Skip the planning phase.
+ skip_planning: false
+
+# Maximum wall-clock time per attempt. Uses Go duration syntax: "30m", "1h", "45s".
+# 0 or omitted means no limit.
+timeout: "30m"
+
+retry:
+ # Total attempts including the first run. Must be >= 1.
+ max_attempts: 3
+ # "linear" or "exponential"
+ backoff: "exponential"
+
+# Scheduling priority: high | normal | low
+priority: "normal"
+
+# Arbitrary labels for filtering.
+tags:
+ - "bug"
+ - "auth"
+
+# IDs of tasks that must reach COMPLETED before this task is queued.
+depends_on:
+ - "setup-test-db"
+```
+
+---
+
+## Batch File Format
+
+A batch file wraps multiple task definitions under a `tasks:` key. All top-level task fields are supported per entry.
+
+```yaml
+tasks:
+ - name: "Step 1 — scaffold"
+ agent:
+ instructions: "Create the initial project structure."
+ priority: "high"
+
+ - name: "Step 2 — implement"
+ agent:
+ instructions: "Implement the feature described in docs/feature.md."
+ depends_on:
+ - "step-1-id"
+
+ - name: "Step 3 — test"
+ agent:
+ instructions: "Write and run integration tests."
+ depends_on:
+ - "step-2-id"
+ retry:
+ max_attempts: 2
+ backoff: "linear"
+```
+
+`ParseFile` / `Parse` detect the batch format automatically: if unmarshaling into `BatchFile` succeeds and produces at least one task, the batch path is used; otherwise single-task parsing is attempted.
+
+---
+
+## State Constants
+
+```go
+type State string
+
+const (
+ StatePending State = "PENDING"
+ StateQueued State = "QUEUED"
+ StateRunning State = "RUNNING"
+ StateReady State = "READY"
+ StateCompleted State = "COMPLETED"
+ StateFailed State = "FAILED"
+ StateTimedOut State = "TIMED_OUT"
+ StateCancelled State = "CANCELLED"
+ StateBudgetExceeded State = "BUDGET_EXCEEDED"
+ StateBlocked State = "BLOCKED"
+)
+```
+
+| Constant | String value | Description |
+|-----------------------|-------------------|-------------------------------------------------------------------------------------------------------|
+| `StatePending` | `PENDING` | Newly created; awaiting acceptance for scheduling. |
+| `StateQueued` | `QUEUED` | Accepted by the scheduler and waiting for an available executor. |
+| `StateRunning` | `RUNNING` | An agent is actively executing the task. |
+| `StateReady` | `READY` | Agent finished execution; output is awaiting human review/approval. |
+| `StateCompleted` | `COMPLETED` | Approved and finished. **Terminal** — no further transitions. |
+| `StateFailed` | `FAILED` | Execution failed (non-zero exit or unrecoverable error). Eligible for retry → `QUEUED`. |
+| `StateTimedOut` | `TIMED_OUT` | Execution exceeded the configured `timeout`. Eligible for retry or resume → `QUEUED`. |
+| `StateCancelled` | `CANCELLED` | Manually cancelled. Can be restarted by transitioning back to `QUEUED`. |
+| `StateBudgetExceeded` | `BUDGET_EXCEEDED` | The `max_budget_usd` cap was reached during execution. Eligible for retry → `QUEUED`. |
+| `StateBlocked` | `BLOCKED` | The running agent posted a question requiring a human response before it can continue. |
+
+---
+
+## State Machine
+
+### Valid Transitions
+
+| From | To | Condition |
+|---------------------|---------------------|-------------------------------------------------------------------|
+| `PENDING` | `QUEUED` | Task accepted for scheduling. |
+| `PENDING` | `CANCELLED` | Manually cancelled before queuing. |
+| `QUEUED` | `RUNNING` | An executor picks up the task. |
+| `QUEUED` | `CANCELLED` | Manually cancelled while waiting in queue. |
+| `RUNNING` | `READY` | Agent finished; output ready for human review. |
+| `RUNNING` | `COMPLETED` | Agent finished successfully with no review required. |
+| `RUNNING` | `FAILED` | Agent exited with an error. |
+| `RUNNING` | `TIMED_OUT` | Wall-clock timeout exceeded. |
+| `RUNNING` | `CANCELLED` | Manually cancelled mid-execution. |
+| `RUNNING` | `BUDGET_EXCEEDED` | API spend reached `max_budget_usd`. |
+| `RUNNING` | `BLOCKED` | Agent posted a question requiring human input before continuing. |
+| `READY` | `COMPLETED` | Reviewer approves the output. |
+| `READY` | `PENDING` | Reviewer rejects the output; task sent back for revision. |
+| `FAILED` | `QUEUED` | Retry: task re-queued for another attempt. |
+| `TIMED_OUT` | `QUEUED` | Retry or resume: task re-queued. |
+| `CANCELLED` | `QUEUED` | Restart: task re-queued from scratch. |
+| `BUDGET_EXCEEDED` | `QUEUED` | Retry with adjusted budget. |
+| `BLOCKED` | `QUEUED` | Answer provided; task re-queued to resume. |
+| `BLOCKED` | `READY` | Question resolved; output is ready for review. |
+| `COMPLETED` | *(none)* | Terminal state — no outgoing transitions. |
+
+---
+
+## Key Functions
+
+### `ParseFile`
+
+```go
+func ParseFile(path string) ([]Task, error)
+```
+
+Reads a YAML file at `path` and returns the parsed tasks. Supports both single-task and batch formats. Initialises defaults (UUID, priority, retry policy, initial state, timestamps) on every returned task.
+
+### `Parse`
+
+```go
+func Parse(data []byte) ([]Task, error)
+```
+
+Same as `ParseFile` but operates on raw YAML bytes instead of a file path.
+
+### `ValidTransition`
+
+```go
+func ValidTransition(from, to State) bool
+```
+
+Returns `true` if transitioning from `from` to `to` is permitted by the state machine. Used by `storage.DB.UpdateTaskState` to enforce valid transitions inside a transaction.
+
+### `Validate`
+
+```go
+func Validate(t *Task) error
+```
+
+Checks a task for constraint violations. Returns a `*ValidationError` (implementing `error`) listing all violations, or `nil` if the task is valid. All violations are collected before returning so callers receive the full list at once.
+
+---
+
+## Validation Rules
+
+| Rule | Error message |
+|------------------------------------------------------------------------------|--------------------------------------------------------------------|
+| `name` must be non-empty. | `name is required` |
+| `agent.instructions` must be non-empty. | `agent.instructions is required` |
+| `agent.max_budget_usd` must be ≥ 0. | `agent.max_budget_usd must be non-negative` |
+| `timeout` must be ≥ 0. | `timeout must be non-negative` |
+| `retry.max_attempts` must be ≥ 1. | `retry.max_attempts must be at least 1` |
+| `retry.backoff`, if set, must be `linear` or `exponential`. | `retry.backoff must be 'linear' or 'exponential'` |
+| `priority`, if set, must be `high`, `normal`, or `low`. | `invalid priority "…"; must be high, normal, or low` |
+| `agent.permission_mode`, if set, must be one of the six recognised values. | `invalid permission_mode "…"` |