Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
1c8b7c5
feat(taskctl): Phase 1 — task store, scheduler, validation, CRUD tool…
Feb 19, 2026
433fd04
feat(taskctl): Phase 2 — Composer agent and taskctl start command (#203)
Feb 19, 2026
01022da
feat(taskctl): Phase 3a — Pulse core loop: heartbeat, scheduling, sin…
Feb 19, 2026
37bca8e
feat(taskctl): Phase 3c — PM commands: status, stop, resume, override…
Feb 19, 2026
3b105d0
feat(taskctl): Phase 3b — developer/adversarial pipeline: verdict too…
Feb 19, 2026
df8829a
Merge Phase 3c: PM commands into feature/taskctl-pipeline
Feb 19, 2026
da387f9
fix(taskctl): use unique temp dir in pipeline tests to prevent collision
Feb 19, 2026
db05cf9
Merge Phase 3b: developer/adversarial pipeline into feature/taskctl-p…
Feb 19, 2026
51ec36f
feat(taskctl): Phase 4 — steering agent + adversarial timeout recover…
Feb 19, 2026
67f9ab9
feat(taskctl): Phase 5 — agent definitions in codebase + AGENTS.md do…
Feb 19, 2026
a8ece62
Merge Phase 4: steering agent + adversarial timeout recovery into fea…
Feb 19, 2026
9238e11
Merge Phase 5: PM prompt migration + AGENTS.md documentation into fea…
Feb 19, 2026
2b3e065
fix(taskctl): strengthen sanitizeWorktree against mid-path traversal
Feb 19, 2026
d22ab90
fix(taskctl): spawnSteering parses actual agent response, improve che…
Feb 19, 2026
d8cb50f
fix(taskctl): sanitize worktree paths in override/retry commands, rem…
Feb 19, 2026
5f46916
fix(taskctl): replace as any with MessageV2.TextPart in spawnSteering…
Feb 19, 2026
07c7dd0
fix(cancel_task): check parent_session_id for ownership, not child se…
Feb 19, 2026
c244604
ci: trigger CI for PR #227
Feb 19, 2026
614d36c
Merge branch 'origin/dev' into feature/taskctl-pipeline - resolve too…
Feb 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 157 additions & 1 deletion .fork-features/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,162 @@
"symlink resolution"
]
}
},
"taskctl": {
"status": "active",
"description": "Autonomous pipeline for managing task graphs with dependencies, priority ordering, conflict detection, and adversarial workflow. Phase 1 includes types, store, scheduler, validation, and CLI tool. Phase 2 adds Composer agent for automatic issue decomposition, taskctl start command for spawning full pipeline. Phase 3 adds Pulse execution engine with heartbeat, scheduling, singleton lock, crash recovery, and timeout detection. Phase 3a adds adversarial workflow integration with pipeline stages (developing, reviewing, adversarial, steering), verdict tracking, and auto-retry logic. Phase 3b adds agent.ts integration for spawning adversarial sessions (developer-pipeline and adversarial-pipeline agent definitions). Phase 3c adds PM control commands: status, stop, resume, override, retry, inspect for manual pipeline intervention. Phase 4 adds self-healing steering agent (evaluates progress every 15 min, sends guidance or replaces developer), improved adversarial timeout detection (60 min), and session message retrieval for activity summaries. Phase 5 updates AGENTS.md with taskctl documentation section describing pipeline workflow and PM commands.",
"issue": "https://github.com/randomm/opencode/issues/207",
"newFiles": [
"packages/opencode/src/tasks/types.ts",
"packages/opencode/src/tasks/store.ts",
"packages/opencode/src/tasks/scheduler.ts",
"packages/opencode/src/tasks/validation.ts",
"packages/opencode/src/tasks/composer.ts",
"packages/opencode/src/tasks/pulse.ts",
"packages/opencode/src/tasks/tool.ts",
"packages/opencode/src/tasks/index.ts",
"packages/opencode/src/tasks/LIMITATIONS.md",
"packages/opencode/test/tasks/store.test.ts",
"packages/opencode/test/tasks/scheduler.test.ts",
"packages/opencode/test/tasks/validation.test.ts",
"packages/opencode/test/tasks/composer.test.ts",
"packages/opencode/test/tasks/pulse.test.ts",
"packages/opencode/test/tasks/commands.test.ts",
"packages/opencode/test/tasks/steering.test.ts"
],
"modifiedFiles": ["packages/opencode/src/tool/registry.ts", "packages/opencode/src/agent/agent.ts", "packages/opencode/src/tasks/pulse.ts", "AGENTS.md"],
"deletedFiles": [],
"criticalCode": [
"sanitizeProjectId",
"sanitizeTaskId",
"getSafeTaskPath",
"IMMUTABLE_FIELDS",
"validateTaskUpdates",
"const TASKS_DIR = \"tasks\"",
"getTasksDir",
"atomicWrite",
"Store.createTask",
"Store.getTask",
"Store.updateTask",
"Store.listTasks",
"Store.updateIndex",
"Store.getIndex",
"Store.logActivity",
"Store.createJob",
"Store.getJob",
"Store.updateJob",
"Store.addComment",
"Store.addPipelineEvent",
"Store.findJobByIssue",
"Scheduler.getNextTasks",
"Validation.validateGraph",
"Validation.validateGraphFromMap",
"startPulse",
"tickStartTime",
"resurrectionScan",
"isSessionAlive",
"lock file management",
"writeLockFile",
"readLockPid",
"removeLockFile",
"isPidAlive",
"checkTimeouts",
"TIMEOUT_MS",
"checkCompletion",
"gracefulStop",
"heartbeatActiveAgents",
"Pulse tick overlap guard",
"Atomic lock file write",
"Crash recovery",
"Worker session spawn",
"TaskctlTool",
"taskctl create",
"taskctl list",
"taskctl get",
"taskctl update",
"taskctl close",
"taskctl comment",
"taskctl depends",
"taskctl split",
"taskctl next",
"taskctl validate",
"taskctl start",
"taskctl start-skip",
"taskctl status",
"taskctl stop",
"taskctl resume",
"taskctl inspect",
"taskctl override",
"taskctl retry",
"command enum (stop, resume, inspect, override, retry)",
"overrideMode parameter (skip, commit-as-is)",
"Terminal state rejection (complete/failed/stopped)",
"Pulse-zombie detection in stop command",
"Job stopping flag validation",
"Session cancellation and worktree cleanup",
"composer agent",
"runComposer",
"Circular dependency detection",
"Missing dependency detection",
"Acceptance criteria warning",
"Conflict label warning",
"Priority ordering (0=highest)",
"Dependency filtering",
"Self-dependency prevention",
"Duplicate dependency check",
"Status validation (only split open, prevent re-close)",
"MAX_COMMENT_LENGTH",
"maxAttempts (1000)",
"append-only.ndjson",
"activity.ndjson",
"index.json",
"slug generation",
"conflict detection",
"steering agent",
"checkSteering",
"spawnSteering",
"getRecentActivity",
"Session.messages()",
"15-minute steering evaluation",
"continue/steer/replace",
"ADVERSARIAL_TIMEOUT_MS = 60 * 60 * 1000",
"adversarial-running stage timeout",
"Steering guidance via SessionPrompt",
"Developer replacement logic"
],
"tests": [
"packages/opencode/test/tasks/store.test.ts",
"packages/opencode/test/tasks/scheduler.test.ts",
"packages/opencode/test/tasks/validation.test.ts",
"packages/opencode/test/tasks/composer.test.ts",
"packages/opencode/test/tasks/pulse.test.ts",
"packages/opencode/test/tasks/commands.test.ts",
"packages/opencode/test/tasks/steering.test.ts"
],
"upstreamTracking": {
"absorptionSignals": [
"TASKS_DIR",
"taskctl",
"Composer",
"runComposer",
"Scheduler.getNextTasks",
"Validation.validateGraph",
"Validation.validateGraphFromMap",
"sanitizeProjectId",
"sanitizeTaskId",
"IMMUTABLE_FIELDS",
"task.*pipeline.*adversarial",
"Circular dependency",
"conflict labels",
"module:.*file:",
"activity.ndjson",
"atomicWrite",
"slug.*generation",
"LIMITATIONS.md",
"TOCTOU",
"concurrent operation"
]
}
}
}
}
}
38 changes: 38 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,44 @@ bun test:e2e:local # Run Playwright E2E tests

---

## taskctl: Autonomous Task Pipeline

`taskctl` is a built-in tool that automates the development loop for GitHub issues.
PM calls `taskctl start <issueNumber>` and the pipeline handles decomposition, development, review, and committing automatically.

### How it works

1. **Composer** — decomposes the GitHub issue into a dependency graph of tasks
2. **Pulse** — a 5-second deterministic loop that schedules developer agents, monitors progress, and processes review verdicts
3. **developer-pipeline** — implements tasks with TDD, signals completion via `taskctl comment`
4. **adversarial-pipeline** — reviews code and writes structured verdict via `taskctl verdict`
5. **Steering** — assessed every 15 minutes: sends guidance or replaces stuck developers
6. **@ops** — commits approved work to the feature branch

PM is only interrupted when a task fails after 3 adversarial cycles, or when all tasks complete.

### PM workflow with taskctl

```bash
taskctl start <issueNumber> # Decompose issue and start pipeline
taskctl status <issueNumber> # Live dashboard — tasks, states, Pulse health
taskctl inspect <taskId> # Full history of a specific task
taskctl stop <jobId> # Gracefully halt pipeline (work preserved)
taskctl resume <jobId> # Resume a stopped or crashed pipeline
taskctl retry <taskId> # Reset a stuck task for fresh attempt
taskctl override <taskId> --skip # Skip a task, unblock dependents
taskctl override <taskId> --commit-as-is # Commit despite issues (PM responsibility)
```

### Source locations

- Tool commands: `packages/opencode/src/tasks/tool.ts`
- Pipeline engine: `packages/opencode/src/tasks/pulse.ts`
- Agent definitions: `packages/opencode/src/agent/agent.ts`
- Design document: `lievo/plan-v2.md` (git-ignored, local only)

---

## Build & Install Binaries

### Main opencode TUI
Expand Down
Loading