@ob1-sg/horizon 0.1.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Brandon Ong
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,344 @@
1
+ # Horizon - Autonomous Product Development Agent
2
+
3
+ Horizon is an AI-powered autonomous development system that works on Linear tickets without human intervention. It orchestrates multiple AI agents to research, plan, implement, and validate code changes, all while keeping Linear updated with progress.
4
+
5
+ ## Installation
6
+
7
+ ### Global Installation (Recommended)
8
+
9
+ ```bash
10
+ npm install -g @ob1-sg/horizon
11
+ ```
12
+
13
+ ### Local Project Installation
14
+
15
+ ```bash
16
+ npm install --save-dev @ob1-sg/horizon
17
+ ```
18
+
19
+ ## Quick Start
20
+
21
+ 1. **Install Horizon** (see above)
22
+
23
+ 2. **Run Horizon**:
24
+ ```bash
25
+ cd your-project
26
+ horizon # Global install
27
+ npx horizon # Local install
28
+ ```
29
+
30
+ 3. **First-run setup** - On first run, Horizon will:
31
+ - Prompt for your Linear API key
32
+ - Auto-detect your Linear team
33
+ - Create necessary directories and configuration
34
+ - Start the development loop
35
+
36
+ 4. **Create tickets** in Linear and Horizon will work on them autonomously
37
+
38
+ For advanced configuration, run `horizon config` to change settings like provider, model, and iteration limits.
39
+
40
+ ## How It Works
41
+
42
+ Horizon uses three core concepts: **Pods**, **Loops**, and **Agents**.
43
+
44
+ ### Pods, Loops, and Agents
45
+
46
+ ```
47
+ ┌─────────────────────────────────────────────────────────────────────────┐
48
+ │ Pod (swift-wyvern) │
49
+ ├─────────────────────────────────────────────────────────────────────────┤
50
+ │ │
51
+ │ Loop 1: Ticket RSK-42 │
52
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
53
+ │ │ Agent 1 │ │ Agent 2 │ │ Agent 3 │ │
54
+ │ │ Linear │────▶│ Worker │────▶│ Linear │ │
55
+ │ │ Reader │ │ │ │ Writer │ │
56
+ │ └──────────────┘ └──────────────┘ └──────────────┘ │
57
+ │ │
58
+ │ Loop 2: Ticket RSK-43 │
59
+ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
60
+ │ │ Agent 1 │────▶│ Agent 2 │────▶│ Agent 3 │ │
61
+ │ └──────────────┘ └──────────────┘ └──────────────┘ │
62
+ │ │
63
+ │ Loop 3: ... │
64
+ │ │
65
+ └─────────────────────────────────────────────────────────────────────────┘
66
+ ```
67
+
68
+ - **Pod**: A running instance of Horizon. Each pod gets a unique name (e.g., "swift-wyvern") and continuously processes tickets until stopped. You can run multiple pods in parallel.
69
+
70
+ - **Loop**: One complete cycle of work. Each loop claims a ticket, works on it, and updates Linear. A pod runs loops continuously until there's no more work.
71
+
72
+ - **Agent**: An AI worker that handles one part of the loop. Three agents work in sequence to complete each loop.
73
+
74
+ ### The Agent Pipeline
75
+
76
+ 1. **Agent 1 (Linear Reader)**: Scans Linear for available tickets, prioritizes by urgency, **claims** the highest-priority ticket, and gathers context.
77
+
78
+ 2. **Agent 2 (Worker)**: The developer. Reads code, writes code, runs tests, and commits changes.
79
+
80
+ 3. **Agent 3 (Linear Writer)**: Updates Linear with results - posts comments, updates status, and links commits.
81
+
82
+ ### Parallel Execution
83
+
84
+ Multiple pods can work on the same codebase simultaneously. Horizon prevents conflicts through **ticket claiming**:
85
+
86
+ 1. When Agent 1 finds a ticket to work on, it immediately changes the status to "In Progress"
87
+ 2. Other pods see this status and skip the ticket
88
+ 3. Each pod works on different tickets, avoiding collisions
89
+
90
+ This lets you scale development by running multiple Horizon pods in parallel - on different machines, in CI, or as background processes.
91
+
92
+ ### Linear as State Machine
93
+
94
+ Horizon uses Linear as its state machine. You don't need to configure Horizon or tell it what to work on - just add tickets to Linear and Horizon handles the rest.
95
+
96
+ ```
97
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
98
+ │ ∞ Needs │────▶│ ∞ Needs │────▶│ ∞ Needs │────▶│ ∞ Needs │────▶│ ∞ Needs │
99
+ │ Research │ │ Spec* │ │ Plan │ │ Implement │ │ Validate │
100
+ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
101
+ │ │ │ │ │
102
+ ▼ ▼ ▼ ▼ ▼
103
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
104
+ │ ∞ Research │ │ ∞ Spec In │ │ ∞ Plan In │ │∞ Implement │ │ ∞ Validate │
105
+ │ In Progress │ │ Progress* │ │ Progress │ │ In Progress │ │ In Progress │
106
+ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
107
+
108
+ * Specification is optional - only when ▼
109
+ research determines UX decisions are needed ┌─────────────┐
110
+ │ ∞ Done │
111
+ └─────────────┘
112
+ ```
113
+
114
+ **How it works:**
115
+
116
+ 1. **You create a ticket** in Linear and set its status to `∞ Needs Research` (or any "Needs" status)
117
+ 2. **Horizon picks it up** - Agent 1 scans for tickets in "Needs" statuses
118
+ 3. **Horizon claims it** - Changes status to "In Progress" so other pods skip it
119
+ 4. **Horizon works on it** - Agent 2 does the actual development work
120
+ 5. **Horizon advances it** - Agent 3 moves the ticket to the next status
121
+ 6. **Repeat** until the ticket reaches `∞ Done`
122
+
123
+ This means you can queue up work by creating tickets, and Horizon will process them in priority order. You can also intervene at any point - move a ticket back to a "Needs" status and Horizon will re-do that step.
124
+
125
+ ## Directory Structure
126
+
127
+ After running Horizon, your project will have:
128
+
129
+ ```
130
+ your-project/
131
+ ├── .horizon/ # Runtime data (gitignored)
132
+ │ ├── env # Configuration and credentials
133
+ │ ├── mcp.json # MCP configuration for Claude Code
134
+ │ ├── output/ # Runtime logs
135
+ │ └── attachments/ # Downloaded issue attachments
136
+ ├── horizon-docs/ # Work artifacts (committed)
137
+ │ ├── research/ # Research documents
138
+ │ ├── plans/ # Implementation plans
139
+ │ └── validation/ # Validation reports
140
+ └── CLAUDE.md # Your project's Claude instructions
141
+ ```
142
+
143
+ ## Configuration
144
+
145
+ ### Environment Variables
146
+
147
+ Set these in `.horizon/env` or export them:
148
+
149
+ | Variable | Description | Default |
150
+ |----------|-------------|---------|
151
+ | `LINEAR_API_KEY` | Your Linear API key | (required) |
152
+ | `LINEAR_TEAM_KEY` | Linear team identifier (e.g., "RSK") | (required) |
153
+ | `HORIZON_PROVIDER` | AI provider: "claude" or "codex" | "claude" |
154
+ | `HORIZON_CLAUDE_MODEL` | Claude model: "opus", "sonnet", "haiku" | "opus" |
155
+ | `HORIZON_MAX_ITERATIONS` | Stop after N iterations (0 = unlimited) | 0 |
156
+ | `HORIZON_MERGE_MODE` | Merge mode: "merge" or "pr" | "merge" |
157
+
158
+ ### Merge Modes
159
+
160
+ Horizon supports two modes for completing work:
161
+
162
+ **Direct Merge (default)**
163
+ ```bash
164
+ export HORIZON_MERGE_MODE=merge
165
+ ```
166
+ Horizon merges completed work directly to main. Best for trusted autonomous operation.
167
+
168
+ **Pull Request Mode**
169
+ ```bash
170
+ export HORIZON_MERGE_MODE=pr
171
+ ```
172
+ Horizon creates a pull request instead of merging. The ticket moves to `∞ Awaiting Merge` status until a human reviews and merges the PR. Best for teams that want human oversight.
173
+
174
+ ### Using Codex CLI as Provider
175
+
176
+ When using Codex (`HORIZON_PROVIDER=codex`), configure Linear MCP in Codex:
177
+
178
+ ```bash
179
+ codex mcp add linear --url https://mcp.linear.app/mcp
180
+ ```
181
+
182
+ ## CLI Commands
183
+
184
+ ```bash
185
+ horizon # Run the main development loop
186
+ horizon config # Configure Horizon settings
187
+ horizon uninstall # Remove Horizon from current project
188
+ horizon --help # Show help
189
+ horizon --version # Show version
190
+ ```
191
+
192
+ ## Updates
193
+
194
+ Horizon automatically checks for updates once per day. When a new version is available, you'll see a notification on startup:
195
+
196
+ ```
197
+ Update available: 0.1.3 → 0.1.4
198
+ Run: npm install -g @ob1-sg/horizon@latest
199
+ ```
200
+
201
+ Update with:
202
+
203
+ ```bash
204
+ npm install -g @ob1-sg/horizon@latest
205
+ ```
206
+
207
+ ## Releasing (Maintainers)
208
+
209
+ Releases are performed via GitHub Actions.
210
+
211
+ ### Preflight
212
+
213
+ 1. Confirm GitHub repo secrets:
214
+ - `NPM_TOKEN` (required): npm publish token with access to publish `@ob1-sg/horizon`.
215
+ - `RELEASE_TOKEN` (optional): GitHub token/PAT with `contents: write` in case `github.token` can’t push to `main` due to branch protections (also used to create the GitHub Release).
216
+ 2. Confirm no other release run is in progress (the workflow uses `concurrency: release`).
217
+
218
+ ### Optional: dry run (CI gates only)
219
+
220
+ 1. GitHub → Actions → `Release` → Run workflow (branch: `main`)
221
+ 2. Inputs:
222
+ - `release_type`: `patch`
223
+ - `npm_tag`: `latest`
224
+ - `dry_run`: `true`
225
+ 3. Expectation: build/typecheck/tests run and pass; **no** version bump commit, tag, GitHub Release, or npm publish is created.
226
+
227
+ ### Patch release
228
+
229
+ 1. GitHub → Actions → `Release` → Run workflow (branch: `main`)
230
+ 2. Inputs:
231
+ - `release_type`: `patch` (or `minor` / `major`)
232
+ - `npm_tag`: `latest` (or another intended dist-tag)
233
+ - `dry_run`: `false`
234
+ 3. Expected outputs:
235
+ - A commit on `main` with message like `chore(release): vX.Y.Z`
236
+ - A git tag `vX.Y.Z` pushed to the repo
237
+ - A GitHub Release created for `vX.Y.Z` (auto-generated notes)
238
+ - `@ob1-sg/horizon@X.Y.Z` published to npm under the chosen dist-tag
239
+
240
+ ### Recovery (partial failures)
241
+
242
+ - **Tag exists but npm publish failed**: GitHub → Actions → `Publish existing ref to npm`
243
+ - `ref`: the tag (e.g. `vX.Y.Z`)
244
+ - `npm_tag`: the intended dist-tag (default `latest`)
245
+ - **npm publish succeeded but GitHub Release creation failed**: create a GitHub Release from the existing tag (UI or `gh release create vX.Y.Z --generate-notes`).
246
+
247
+ ### Rollback (only if necessary)
248
+
249
+ If a tag was created but should not exist (and npm publish did not occur):
250
+
251
+ ```bash
252
+ git tag -d vX.Y.Z && git push origin :refs/tags/vX.Y.Z
253
+ ```
254
+
255
+ Delete the GitHub Release for that tag in the UI if one was created.
256
+
257
+ ### Local parity checks (optional)
258
+
259
+ ```bash
260
+ npm ci
261
+ npm run build
262
+ npm run typecheck
263
+ npm test
264
+ ```
265
+
266
+ ## Linear Workflow Statuses
267
+
268
+ Horizon creates these statuses in Linear:
269
+
270
+ **Ready statuses** (waiting for Horizon):
271
+ - `∞ Needs Research`
272
+ - `∞ Needs Specification` (optional - when UX decisions are needed)
273
+ - `∞ Needs Plan`
274
+ - `∞ Needs Implement`
275
+ - `∞ Needs Validate`
276
+
277
+ **In Progress statuses** (Horizon is working):
278
+ - `∞ Research In Progress`
279
+ - `∞ Specification In Progress`
280
+ - `∞ Plan In Progress`
281
+ - `∞ Implement In Progress`
282
+ - `∞ Validate In Progress`
283
+
284
+ **Intervention statuses** (requires human action):
285
+ - `∞ Blocked` - Agent needs clarification or decision before proceeding
286
+ - `∞ Awaiting Merge` - Work complete, PR awaiting human review/merge (PR mode only)
287
+
288
+ **Terminal statuses**:
289
+ - `∞ Done`
290
+ - `∞ Canceled`
291
+
292
+ ## Writing Good Tickets
293
+
294
+ Horizon works best with clear, specific tickets:
295
+
296
+ **Good ticket**:
297
+ > Add a dark mode toggle to the settings page. Should save preference to localStorage and apply a .dark-theme class to the body.
298
+
299
+ **Tips**:
300
+ - Include acceptance criteria when possible
301
+ - Reference existing code patterns to follow
302
+ - Specify any constraints or requirements
303
+ - Link related issues if dependencies exist
304
+
305
+ ## Developing Horizon
306
+
307
+ If you want to contribute or modify Horizon:
308
+
309
+ ```bash
310
+ # Clone the repo
311
+ git clone https://github.com/ob1-sg/horizon
312
+ cd horizon
313
+
314
+ # Install dependencies
315
+ npm install
316
+
317
+ # Build
318
+ npm run build
319
+
320
+ # Run from source
321
+ npm start
322
+
323
+ # Type check
324
+ npm run typecheck
325
+ ```
326
+
327
+ ## Prerequisites
328
+
329
+ - Node.js 18+
330
+ - [Claude Code](https://claude.ai/claude-code) or Codex CLI installed
331
+ - A Linear account with API access
332
+ - Git repository initialized
333
+
334
+ ## Acknowledgments
335
+
336
+ Horizon builds on ideas and techniques from the AI engineering community:
337
+
338
+ - **[Dex Horthy](https://github.com/humanlayer/advanced-context-engineering-for-coding-agents/blob/main/ace-fca.md)** - For the research/plan/implement pattern that structures how Horizon approaches work
339
+ - **[Geoff Huntley](https://ghuntley.com/ralph/)** - For the Ralph Wiggum technique that inspires Horizon's autonomous agent approach
340
+ - **[Vaibhav @ BoundaryML](https://boundaryml.com/podcast)** - For BAML and the "AI That Works" podcast series on building reliable AI systems
341
+
342
+ ## License
343
+
344
+ MIT
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@ob1-sg/horizon",
3
+ "version": "0.1.10",
4
+ "description": "Linear-orchestrated autonomous agent system",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "horizon": "dist/cli.js"
9
+ },
10
+ "files": [
11
+ "dist/**/*",
12
+ "prompts/**/*"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "start": "node dist/cli.js",
17
+ "dev": "tsc --watch",
18
+ "typecheck": "tsc --noEmit",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest"
21
+ },
22
+ "engines": {
23
+ "node": ">=18.0.0"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/ob1-sg/horizon.git"
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "keywords": [
33
+ "ai",
34
+ "autonomous",
35
+ "linear",
36
+ "developer",
37
+ "agent",
38
+ "claude",
39
+ "horizon"
40
+ ],
41
+ "author": "OB1",
42
+ "license": "MIT",
43
+ "homepage": "https://github.com/ob1-sg/horizon",
44
+ "dependencies": {
45
+ "@linear/sdk": "^31.0.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20.10.0",
49
+ "typescript": "^5.3.0",
50
+ "vitest": "^4.0.18"
51
+ }
52
+ }
@@ -0,0 +1,248 @@
1
+ # Agent 1: Linear Reader
2
+
3
+ **EXECUTE NOW.** Query Linear and select work for the Worker agent.
4
+
5
+ Your job:
6
+ 1. Get all available issue statuses for the team
7
+ 2. Get all non-completed issues from Linear
8
+ 3. Check for stale `∞ ... In Progress` issues and reset them
9
+ 4. Select the highest-priority issue ready for work
10
+ 5. Gather full context including related issues
11
+ 6. Claim it and output the details for Agent 2
12
+
13
+ ## Important: Parallel Execution Environment
14
+
15
+ Multiple agents may be running simultaneously and looking at issues together. This means:
16
+
17
+ 1. **Statuses can change at any time** - Another agent may claim an issue between when you fetch and when you try to claim
18
+ 2. **Always use fresh data** - Before claiming, re-check the current status to minimize conflicts
19
+ 3. **Handle claim failures gracefully** - If claiming fails (issue already claimed), simply move on to the next best issue
20
+
21
+ ### Best Practices for Parallel Execution:
22
+ - Prefer issues that have been in their current status longer (less likely to be targeted by other agents)
23
+ - If you see an issue transition to an `∞ ... In Progress` status after your initial fetch, skip it
24
+ - When claiming, verify the status hasn't changed before updating
25
+ - **Pod Continuity**: If an `∞ ... In Progress` issue was claimed by a different loop instance (pod) within the last hour, prefer other available work—this lets the same pod complete all stages of a feature; only consider taking over if no other work is available or the claim is older than 1 hour
26
+
27
+ ## Execute These Steps
28
+
29
+ ### Step 1: Get Available Statuses
30
+
31
+ Use `mcp__linear__list_issue_statuses` with the team parameter to get all available workflow statuses.
32
+
33
+ **IMPORTANT**: Horizon uses `∞` prefixed statuses for its workflow stages. However, Horizon can pick up work from ANY backlog or todo-like status (not just `∞ Backlog`).
34
+
35
+ This gives you the full list of status names and their types. Look for:
36
+
37
+ **Entry Points (any of these can be picked up for work)**:
38
+ - Any status with type "backlog" (e.g., `Backlog`, `∞ Backlog`, `Triage`, etc.)
39
+ - Any status with type "unstarted" (e.g., `Todo`, `Ready`, etc.) - these are "ready to work" statuses
40
+ - Any `∞ Needs ...` status (issues already in Horizon's workflow)
41
+
42
+ **Note on Status Type Hierarchy**:
43
+ 1. First prioritize Horizon's `∞` prefixed statuses (already in workflow)
44
+ 2. Then backlog-type statuses (explicitly waiting for work)
45
+ 3. Then unstarted-type statuses (like "Todo" - ready but not started)
46
+
47
+ **Horizon Workflow Statuses (use these exact names for stage transitions)**:
48
+ - **Ready statuses** (unstarted):
49
+ - `∞ Needs Research`
50
+ - `∞ Needs Specification`
51
+ - `∞ Needs Plan`
52
+ - `∞ Needs Implement`
53
+ - `∞ Needs Validate`
54
+ - **In Progress statuses** (started):
55
+ - `∞ Research In Progress`
56
+ - `∞ Specification In Progress`
57
+ - `∞ Plan In Progress`
58
+ - `∞ Implement In Progress`
59
+ - `∞ Validate In Progress`
60
+ - `∞ Oneshot In Progress`
61
+ - **Intervention status** (requires human action):
62
+ - `∞ Blocked` - Agent needs clarification or decision before proceeding
63
+ - `∞ Awaiting Merge` - Work complete, PR awaiting human review/merge
64
+ - **Done**: `∞ Done`
65
+ - **Canceled**: `∞ Canceled`
66
+
67
+ If you don't see these `∞` statuses, output NO_WORK with reason "Horizon statuses not initialized".
68
+
69
+ ### Step 2: Get Issues (Excluding Completed/Canceled)
70
+
71
+ To avoid cluttering context with completed work, make **separate queries** for the statuses Horizon can work on. Use `mcp__linear__list_issues` with these parameters:
72
+
73
+ **Query 1**: Get backlog and todo issues (entry points for new work)
74
+
75
+ Query ALL backlog-type AND unstarted-type statuses identified in Step 1. This includes not just `∞ Backlog` but any status that represents "ready for work". Make separate calls for each:
76
+ - `state: "∞ Backlog"`, `includeArchived: false`
77
+ - `state: "Backlog"`, `includeArchived: false` (if this status exists)
78
+ - `state: "Todo"`, `includeArchived: false` (if this status exists)
79
+ - Any other backlog-type or unstarted-type statuses found in Step 1
80
+
81
+ **Important**: Always query all entry point statuses. If `∞ Backlog` is empty, there may still be work available in other statuses like `Backlog`, `Todo`, or `Triage`. The goal is to find any work that is ready to be picked up.
82
+
83
+ **Exclusions**: Do NOT pick up issues from standard started-type statuses like `In Progress` or `In Review` - these are being actively worked on by humans. Only pick up from backlog-type and unstarted-type statuses (which represent "waiting for work" states).
84
+
85
+ **Query 2**: Get issues in Horizon workflow ready for work
86
+ Make separate calls for each `∞ Needs *` status:
87
+ - `state: "∞ Needs Research"`, `includeArchived: false`
88
+ - `state: "∞ Needs Specification"`, `includeArchived: false`
89
+ - `state: "∞ Needs Plan"`, `includeArchived: false`
90
+ - `state: "∞ Needs Implement"`, `includeArchived: false`
91
+ - `state: "∞ Needs Validate"`, `includeArchived: false`
92
+
93
+ **Query 3**: Get in-progress issues (to check for stale claims)
94
+ Make separate calls for each `∞ ... In Progress` status:
95
+ - `state: "∞ Research In Progress"`, `includeArchived: false`
96
+ - `state: "∞ Specification In Progress"`, `includeArchived: false`
97
+ - `state: "∞ Plan In Progress"`, `includeArchived: false`
98
+ - `state: "∞ Implement In Progress"`, `includeArchived: false`
99
+ - `state: "∞ Validate In Progress"`, `includeArchived: false`
100
+ - `state: "∞ Oneshot In Progress"`, `includeArchived: false`
101
+
102
+ **Query 4**: Get blocked issues (for awareness, cannot be picked up)
103
+ - `state: "∞ Blocked"`, `includeArchived: false`
104
+
105
+ **Important**: You can make multiple tool calls in parallel within a single message to speed this up. Only use the `∞` prefixed statuses that were confirmed to exist in Step 1.
106
+
107
+ **Do NOT query for**:
108
+ - `∞ Done`, `Done`, `[RL] Done` (completed)
109
+ - `∞ Canceled`, `Canceled`, `[RL] Canceled`, `Duplicate` (canceled)
110
+ - `∞ Awaiting Merge` (waiting for human to merge PR)
111
+
112
+ This approach fetches only actionable issues and avoids wasting context on completed work.
113
+
114
+ ### Step 3: Check for Stale "∞ ... In Progress" Issues
115
+
116
+ **Note**: In a multi-agent environment, another agent may be actively working on or may have just completed an issue in progress. Be cautious when resetting.
117
+
118
+ For any issue with an `∞ ... In Progress` status:
119
+ 1. Use `mcp__linear__list_comments` to find the most recent "Agent Claimed" comment
120
+ 2. Also check for any "Stage Complete" or "Stage Failed" comments that are more recent than the claim
121
+ 3. If the claim timestamp is more than 4 hours ago AND there are no recent completion comments:
122
+ - **Re-fetch the issue status** before resetting to ensure it hasn't changed
123
+ - If status is still an `∞ ... In Progress` status: Post a timeout reset comment and update status
124
+ - If status has changed: Another agent completed the work, skip resetting this issue
125
+
126
+ ### Step 4: Select the Best Issue
127
+
128
+ **IMPORTANT**: Do NOT list or output all issues. Analyze the issue titles internally and select the single most important issue to work on.
129
+
130
+ #### Hard Filters (must skip these):
131
+
132
+ 1. **Blocked by incomplete dependency**: If an issue has a "blocked by" relationship to another issue that is not yet completed, skip it. The blocker must be finished first.
133
+
134
+ 2. **Claimed by another agent within the last hour**: Check comments for "Agent Claimed" - if another pod claimed it less than 1 hour ago, skip it.
135
+
136
+ 3. **Completed or canceled**: Status type "completed" or "canceled". (Note: These should not appear if Step 2 was followed correctly, but verify as a safety check.)
137
+
138
+ 4. **Blocked status**: Issues in `∞ Blocked` status require human intervention and must not be picked up.
139
+
140
+ #### Soft Preferences (use judgment):
141
+
142
+ After filtering, read the **titles** of remaining issues and use your judgment to pick the most important one:
143
+
144
+ - Consider business impact, urgency, and what would be most valuable to complete
145
+ - Prefer issues that are **blocking other issues** - completing them unblocks more work
146
+ - Prefer issues closer to completion (e.g., `∞ Needs Validate` over `∞ Needs Research`)
147
+ - Prefer to avoid issues currently in an `∞ ... In Progress` status by another pod (even if >1 hour old), but this is not a hard blocker if nothing else is available
148
+
149
+ **Do NOT rely on priority labels** - they are often not populated. Use semantic understanding of the issue titles to determine actual importance.
150
+
151
+ #### If nothing passes hard filters:
152
+
153
+ If all issues are either blocked, recently claimed, or completed, output NO_WORK.
154
+
155
+ ### Step 5: Gather Full Context
156
+
157
+ Use `mcp__linear__get_issue` with `includeRelations: true`.
158
+
159
+ Also gather:
160
+ - **Parent Issue**: Read parent to understand broader goal
161
+ - **Sub-Issues**: List children to understand scope. Note: Some sub-issues may have been created during the planning stage and already have plans. These will typically be in `∞ Needs Implement` status.
162
+ - **Project**: Note project context
163
+ - **Blocking/Blocked**: Check dependency relationships
164
+ - **Comments**: Read all comments for previous work and clarifications
165
+
166
+ ### Step 6: Decide Stage
167
+
168
+ Map the issue's current status to the appropriate stage:
169
+ - Any backlog-type status (e.g., `Backlog`, `∞ Backlog`, `Triage`) → research
170
+ - Any unstarted-type status (e.g., `Todo`, `Ready`) → research
171
+ - `∞ Needs Research` → research
172
+ - `∞ Needs Specification` → specification
173
+ - `∞ Needs Plan` → plan
174
+ - `∞ Needs Implement` → implement
175
+ - `∞ Needs Validate` → validate
176
+ - `∞ Oneshot In Progress` → oneshot (for issues already classified by Agent 2)
177
+
178
+ Use the actual status names from Step 1 to determine the appropriate stage.
179
+
180
+ **Note**: Agent 1 no longer decides whether a ticket is oneshot or staged. Agent 2 makes this determination during the research stage based on actual complexity assessment.
181
+
182
+ ### Step 7: Claim the Issue
183
+
184
+ **Important**: Before claiming, re-fetch the issue to confirm it's still available.
185
+
186
+ 1. **Re-check status**: Use `mcp__linear__get_issue` to get the current status
187
+ - If the status has changed from what you saw in Step 4, the issue may have been claimed by another agent
188
+ - If now an `∞ ... In Progress` status: Skip this issue and return to Step 4 to select the next best option
189
+ - If still available: Proceed with claiming
190
+
191
+ 2. **Claim the issue**:
192
+ - Update the status to the appropriate `∞ ... In Progress` status:
193
+ - `∞ Research In Progress`
194
+ - `∞ Specification In Progress`
195
+ - `∞ Plan In Progress`
196
+ - `∞ Implement In Progress`
197
+ - `∞ Validate In Progress`
198
+ - `∞ Oneshot In Progress`
199
+ - Post a comment (include your loop instance name from the Agent Instance section at the top of your prompt):
200
+ ```
201
+ Agent Claimed | {loop instance name} | {TIMESTAMP}
202
+
203
+ **Loop Instance**: {loop instance name}
204
+ **Stage**: {stage}
205
+ **Timeout**: 4 hours
206
+ ```
207
+
208
+ 3. **Handle claim conflicts**: If the status update fails or you detect another agent's recent claim comment:
209
+ - Do NOT retry claiming this issue
210
+ - Return to Step 4 and select the next best available issue
211
+ - If no other issues are available, output NO_WORK
212
+
213
+ ### Step 8: Output for Agent 2
214
+
215
+ Write out all the information Agent 2 needs to do the work:
216
+
217
+ - Issue ID and identifier (e.g., RSK-6)
218
+ - Issue title
219
+ - Full description
220
+ - Stage to execute (research/specification/plan/implement/validate, or oneshot if status is "Oneshot In Progress")
221
+ - Priority
222
+ - Labels
223
+ - Parent issue details (if any)
224
+ - Sub-issues (if any)
225
+ - Blocking/blocked relationships (if any)
226
+ - Project context (if any)
227
+ - Previous comments and any artifact paths mentioned
228
+ - Any other relevant context
229
+
230
+ Just write this naturally - Agent 2 will read your output directly.
231
+
232
+ ## If No Work Available
233
+
234
+ If there are no issues to work on, output:
235
+
236
+ ```
237
+ NO_WORK
238
+
239
+ Reason: {explain why - all done, all in progress, etc.}
240
+ ```
241
+
242
+ ## Reminders
243
+
244
+ - Only use Linear MCP tools
245
+ - Don't read filesystem or write code
246
+ - Output everything Agent 2 needs - they cannot access Linear
247
+ - **Parallel execution**: Multiple agents may be running simultaneously. Always verify status before claiming and handle conflicts gracefully.
248
+ - **Fresh data**: When in doubt, re-fetch issue status before making updates