A shared queue
Linear is the v1 queue in this guide. Agents only touch work marked with the right title pattern, label, status, and assignee.
A shared operating surface for your agents.
01 / Overview
Open Engine turns Linear into a shared operating surface for agents. A working engine has a queue, private setup context, a status ledger, standing updates, a repeatable runner, resumable blockers, human-thread holds, delegated follow-up, and one smoke-tested task.
Linear is the v1 queue in this guide. Agents only touch work marked with the right title pattern, label, status, and assignee.
Your private skills, brand voice, org chart, customer context, and account details live in your own private issue or runtime context.
Every agent updates one status comment in place, so humans can see who is installed, automated, blocked, or stale.
The queue runner checks standing updates, resumes paused work, follows delegated tasks, then processes one assigned task per run.
Copy the full guide context into your AI assistant and have it walk you through the setup one decision at a time.
02 / Before You Start
Do this before asking an agent to process work. Most failed first runs come from mismatched team names, labels, statuses, issue titles, or agent codes.
Pick the Linear team that will own agent work, or create a small team named Agent Engine.
Create one project: Personal Agent Engine for one operator, or Team Agent Engine for a team.
Create the exact label agent-instructions. The runner filters on this spelling.
Choose stable agent codes for every runtime, such as alex-codex, alex-claude, or sam-codex.
Name the private setup issue and status ledger before automation exists, so every prompt points at the same source of truth.
Use this before creating anything in Linear. It turns the naming step into a focused planning conversation.
03 / Step 1
Open Engine only works if your agent can read and update Linear. Connect your runtime to Linear's official MCP server before you build the queue or schedule a runner.
Create or open your Linear workspace at linear.app.
Choose the agent runtime that will run the queue: Codex, Claude Code, Claude Desktop, Cursor, or another MCP-capable client.
Connect that runtime to Linear's official MCP server. The setup command depends on the runtime.
Complete the browser authentication flow with the Linear account that should read and update agent issues.
Run a read test from the agent, then a write test on a throwaway issue before trusting automation.
# Recommended Codex local MCP setup codex mcp add linear --url https://mcp.linear.app/mcp # If this is your first remote MCP in Codex, enable remote MCP in ~/.codex/config.toml: [features] rmcp_client = true # Manual Codex config alternative: [mcp_servers.linear] url = "https://mcp.linear.app/mcp" # Then authenticate: codex mcp login linear
# Claude Code Linear MCP setup claude mcp add --transport sse linear-server https://mcp.linear.app/sse # Then open Claude Code and run: /mcp # Follow the Linear authentication flow and enable the Linear tools for the session.
Verify my Linear connection before we continue setting up Open Engine. Do these checks in order: 1. List the Linear workspaces, teams, or projects you can see. 2. Tell me which Linear account appears to be connected. 3. Find or create one throwaway test issue named [agent instructions][connection-test][task] Verify Linear MCP access. 4. Add a comment to that issue saying AGENT CONNECTION TEST from this runtime. 5. Move or update only that test issue if you have status-write access. 6. Report whether you have read access, comment access, and status-update access. Do not touch any real work issues during this test.
04 / Step 2
Linear is an issue tracker and project-management tool. In Open Engine, it becomes the shared queue: agents read assigned issues, move statuses, leave receipts, and use the issue history as the audit trail.
Durable setup, status, skills, routing maps, SOPs, brand guides, and other versioned context.
Finite assigned tasks waiting for the target operator's agent.
The claim lock. An agent has taken the issue and should leave AGENT CLAIMED.
A paused issue waiting for a Linear answer or human-thread answer.
Completed work that still needs human judgment, quality assurance, or approval.
Completed finite work with a receipt and no further human review required.
Create or choose the Linear team. Statuses belong to a team, so this decision comes before the workflow.
Create the six workflow statuses in order: Standing, Agent Todo, Agent Working, Agent Needs Input, Agent Review, and Agent Done.
Make Agent Done a completed-category status. The other agent statuses are active workflow states.
Create the agent-instructions label and verify you can apply it to a test issue.
Create the Personal Agent Engine or Team Agent Engine project in the same team.
05 / Step 3
The public guide teaches the method. Your private packet teaches the actual engine: local paths, allowed sources, account boundaries, receipt rules, and the context each runtime must load before it acts.
Create a local private context file for each runtime. For Codex, a good default is ~/.codex/skills/open-agent-engine/SKILL.md.
Put the engine version, agent code, Linear team/project, label, allowed sources, status ledger issue, and safety boundaries in that file. Leave the status ledger issue ID as a placeholder until you create the ledger in the next step.
Create a private Standing setup issue titled [agent instructions][all agents][standing_skill] Install Open Agent Engine core context v1.
In that setup issue, list the exact skills/context to install, local paths, smoke-test expectations, and receipt meanings.
Require AGENT APPLIED only after a runtime has actually installed or adapted the target version locally.
--- name: open-agent-engine description: Route assigned Linear agent tasks through the Open Agent Engine queue. version: 1 --- Agent code: alex-codex Human/operator: Alex Example Linear team: Agent Engine Linear project: Personal Agent Engine Agent label: agent-instructions Status ledger issue: ENG-000 # placeholder until you create the ledger in Step 4 Private sources: list approved local folders or private issue ids Rules: - Process at most one eligible task issue per run. - Only process issues assigned to this human/operator. - Only process issues with the agent-instructions label and [agent instructions] in the title. - Only claim task issues whose second title bracket is this agent code, e.g. [agent instructions][alex-codex][task]. Standing issues addressed to [all agents] still apply to every runtime. - Before task work, check standing context versions assigned to this agent or all agents. - Claim by moving the issue to Agent Working and leaving AGENT CLAIMED. - Re-read the issue after claiming. - If complete with no human judgment required, leave AGENT DONE and move to Agent Done. - If complete but review, QA, approval, or inspection is required, leave AGENT DONE and move to Agent Review. - If the missing answer belongs on Linear, ask one specific question, leave AGENT BLOCKED, and move to Agent Needs Input. - If the question is about local runtime permissions, skill install approval, automation setup, account authority, or private agent-thread context, ask in the human's own agent thread/app, leave AGENT HUMAN HOLD, and move to Agent Needs Input. - Ask before publishing, emailing, posting publicly, deploying, changing billing, changing credentials, deleting destructive data, or making customer-facing changes.
<task> Create the private standing setup issue for our Open Engine. </task> <issue> Title: [agent instructions][all agents][standing_skill] Install <Engine Name> core context v<version> Label: agent-instructions Status: Standing </issue> <include> <item>What this engine is for.</item> <item>Status ledger issue ID or URL.</item> <item>Routing map issue ID or URL.</item> <item>Private context packs to install or adapt.</item> <item>Codex setup steps plus manual fallback.</item> <item>Other runtime setup notes where known.</item> <item>Required AGENT AUTOMATION READY receipt after install and smoke test.</item> </include> <privacy> Keep org charts, brand guides, customer context, secrets, account details, and private skill bodies inside this private issue or local runtime context. </privacy>
06 / Step 4
The ledger is how you know which agents are online, automated, blocked, holding, stale, or manual-only. It is a standing issue, not a task to close.
Create the status ledger as a Standing issue with the agent-instructions label.
Paste the AGENT STATUS format into the issue description so every runtime uses the same fields.
Add one manual AGENT STATUS comment before automation exists, then make the runner update that same comment in place.
Use Last queue result values like checking, none, completed ISSUE-ID, blocked ISSUE-ID, holding ISSUE-ID, resumed ISSUE-ID, and failed ISSUE-ID.
Title it [agent instructions][all agents][standing_status] Open Agent Engine status ledger, set status to Standing, and apply agent-instructions.
Each agent owns exactly one top-level AGENT STATUS comment. On every run, update that comment in place instead of adding heartbeat clutter.
Use blocked ISSUE-ID for Linear-answerable blockers, holding ISSUE-ID for human-thread holds, and completed ISSUE-ID only after the task is actually done.
AGENT STATUS Agent: <agent-code> Human/operator: <name or unknown> Runtime: <Codex | Claude | Grok | other> Automation: <automation name or manual> Automation state: <installed | manual-required | blocked | paused> Last heartbeat: <ISO8601 timestamp> Last queue result: <checking | none | observed ISSUE-123 | claimed ISSUE-123 | completed ISSUE-123 | blocked ISSUE-123 | holding ISSUE-123 | resumed ISSUE-123 | failed ISSUE-123> Last successful run: <ISO8601 timestamp or unknown> Local context: <engine version>; <routing map version> Notes: <none or short blocker>
07 / Step 5
The runner is one instruction your agent repeats. A run (its heartbeat) is a single execution of this prompt: you trigger it by hand, or schedule it with your runtime's scheduler or a cron job. Each run checks shared updates, resumes holds and blockers, follows delegated work, then processes exactly one eligible task.
Identify the runtime's agent code, open the status ledger, and update this agent's existing AGENT STATUS comment to checking.
Run standing preflight: compare target versions for shared skills, SOPs, routing maps, voice guides, and safety rules before new task work.
Check AGENT HUMAN HOLD issues first. Resume only after the human answers in their own agent thread or the agent records AGENT HUMAN ANSWERED.
Check AGENT BLOCKED issues next. Resume only after the missing answer appears on the same Linear issue.
Check delegated issues this agent routed to someone else, and leave AGENT FOLLOW-UP if anything changed.
Only then claim the oldest eligible assigned Agent Todo issue, process exactly one task, leave the right receipt, update the ledger, and stop.
<task> Run one Open Engine queue check for this operator. </task> <order> <step>Identify this runtime's agent code.</step> <step>Open the status ledger issue.</step> <step>Find this agent's top-level AGENT STATUS comment.</step> <step>Update that comment in place with Last queue result: checking and the current timestamp.</step> <step>Run standing context preflight before new task work.</step> <step>Check AGENT HUMAN HOLD issues before new task work. If a held issue now shows AGENT HUMAN ANSWERED, move it back to Agent Working, leave AGENT RESUMED, finish it, and stop after this one issue.</step> <step>Check AGENT BLOCKED issues before new task work. If a blocked issue now has its answer on the same issue, move it back to Agent Working, leave AGENT UNBLOCKED then AGENT RESUMED, finish it, and stop after this one issue.</step> <step>Check delegated issues this agent routed to someone else.</step> <step>If no hold or blocked issue is ready to resume, find the oldest eligible Agent Todo task assigned to this operator.</step> <step>Eligible tasks must have the agent-instructions label, [agent instructions] in the title, and this runtime's agent code as the second title bracket, e.g. [agent instructions][alex-codex][task].</step> <step>If no eligible issue exists, update the ledger with Last queue result: none and stop.</step> <step>If an issue exists, move it to Agent Working and leave AGENT CLAIMED.</step> <step>Re-read the issue after claiming.</step> <step>Do only the scoped work.</step> <step>If complete with no human judgment needed, leave AGENT DONE and move to Agent Done.</step> <step>If complete but review, QA, approval, inspection, or publishing is needed, leave AGENT DONE and move to Agent Review.</step> <step>If the missing answer belongs on Linear, ask one specific question, leave AGENT BLOCKED, move to Agent Needs Input, update the ledger with blocked ISSUE-ID, and stop.</step> <step>If the answer belongs in the human's own agent thread/app, ask there, leave AGENT HUMAN HOLD, move to Agent Needs Input, update the ledger with holding ISSUE-ID, and stop.</step> <step>If execution fails unexpectedly, leave AGENT FAILED with the last safe step and retry count.</step> <step>Update the status ledger with completed, blocked, holding, resumed, failed, observed, or claimed for the issue id.</step> <step>Stop after exactly one task issue.</step> </order> <receipts> Use AGENT CLAIMED before work, AGENT DONE when complete, AGENT BLOCKED for Linear-answerable blockers, AGENT HUMAN HOLD for owner-thread permissions, AGENT UNBLOCKED then AGENT RESUMED when a blocked issue's answer arrives, AGENT HUMAN ANSWERED then AGENT RESUMED when a hold is answered, and AGENT FAILED only for unrecoverable failure. </receipts> <boundaries> Never publish, email, Slack-post, deploy, delete, change billing, change credentials, or make outward-facing changes unless the issue explicitly grants that approval. </boundaries>
08 / Receipts
Receipts are the short status comments agents leave on issues and the ledger. Use these exact tokens so every runtime and human reads the loop the same way.
Posted right after moving an issue to Agent Working. The claim lock that stops another runtime from taking the same task.
The scoped work is finished. Pair it with Agent Done when no review is needed, or Agent Review when a human must judge it.
The missing answer belongs on this Linear issue. Ask one specific question and move the issue to Agent Needs Input.
Posted when a blocked issue's answer has arrived on the same issue, immediately before AGENT RESUMED.
The answer belongs in the human's own agent thread or app: permissions, installs, account authority. Move to Agent Needs Input.
Posted on the issue once the human answers a hold in their own thread, clearing it so the work can resume.
Posted when continuing a paused issue, after AGENT UNBLOCKED or AGENT HUMAN ANSWERED.
Unrecoverable failure only. Record the last safe step and the retry count, then stop.
Posted by a runtime after it actually installs or adapts a standing context version locally.
Posted on a delegated issue this agent routed to someone else when that issue's state has changed.
The single top-level ledger comment each agent owns and updates in place on every run.
09 / Step 6
The smoke test should be tiny. You are testing the loop, not the agent's intelligence. Do not trust the engine until claim, done, blocked-resume, and human-hold behavior have all worked.
Create [agent instructions][<your-agent-code>][task] Say hello from the queue. Verify AGENT CLAIMED, AGENT DONE, Agent Done status, and a completed ledger result.
Create an intentionally incomplete issue. The first run should leave AGENT BLOCKED and Agent Needs Input. Answer on the same issue, then verify AGENT UNBLOCKED, AGENT RESUMED, and AGENT DONE.
Ask the agent to request local runtime permission in the current agent thread. Verify AGENT HUMAN HOLD, holding ISSUE-ID on the ledger, AGENT HUMAN ANSWERED after your reply, and then completion.
## Requester <your name>. ## Desired outcome Leave a short comment proving the queue runner claimed and completed this issue. ## Sources None. ## Acceptance criteria - Issue has AGENT CLAIMED from <your-agent-code>. - Issue has AGENT DONE from <your-agent-code>. - Issue moved to Agent Done. - Status ledger says completed for this issue id. ## Boundaries Do not edit files, publish, email, Slack-post, deploy, delete, or change credentials. ## If blocked If the missing answer belongs on Linear, leave AGENT BLOCKED with one specific question. If the missing answer belongs in the human's own agent thread/app, leave AGENT HUMAN HOLD and wait there.
## Desired outcome Draft a one-paragraph update, but only after you know the missing date range. ## Missing information I have intentionally omitted the date range. ## Acceptance criteria - First run leaves AGENT BLOCKED with one specific question. - Issue moves to Agent Needs Input. - Human answers the question on this same issue. - Next run leaves AGENT UNBLOCKED and AGENT RESUMED. - Final run leaves AGENT DONE and moves the issue to Agent Review or Agent Done.
## Desired outcome Ask me in this agent thread whether you may install or update your private local context for this test. ## Acceptance criteria - Agent asks in the current agent thread/app. - Linear issue receives AGENT HUMAN HOLD, not AGENT BLOCKED. - Status ledger says holding for this issue id. - After I answer in this thread, the agent records AGENT HUMAN ANSWERED on Linear and continues or closes the issue.
10 / Team Path
A team engine is the same system with one extra rule: route work to the human who owns the target agent. Do not assign another person's agent task to yourself and expect their automation to see it.
Create a private routing map with each human, Linear assignee, runtime, agent code, and ownership area.
Onboard one teammate at a time: install context, create their AGENT STATUS comment, then run a tiny smoke test assigned to them.
Assign cross-agent work to the human who owns the target agent, not to yourself.
Write every routed task so the target agent can read it cold: requester, outcome, sources, acceptance criteria, output location, boundaries, and pause rule.
Use one standing update issue per shared context family, and let agents compare target version to local version during preflight.
## Agent routing map Alex Example - Linear assignee: Alex Example - Agent codes: alex-codex, alex-claude - Route to Alex for: engineering, local repo work, QA Sam Example - Linear assignee: Sam Example - Agent codes: sam-codex - Route to Sam for: editorial review, social drafts Rules: - If assigning work to Sam's agent, assign the issue to Sam. - If the target agent is not online in the status ledger, say that before relying on the handoff. - If an agent is not listed yet, it may propose a unique agent code, ask its human to fill in the routing details, and leave those details as a comment on this routing map issue. - Human approval is required for publishing and customer-facing changes.
11 / Templates
These are starter contracts. Replace names, issue IDs, setup paths, context families, version numbers, and boundaries before using them with real agents.
<task> Create the private standing setup issue for our Open Engine. </task> <issue> Title: [agent instructions][all agents][standing_skill] Install <Engine Name> core context v<version> Label: agent-instructions Status: Standing </issue> <include> <item>What this engine is for.</item> <item>Status ledger issue ID or URL.</item> <item>Routing map issue ID or URL.</item> <item>Private context packs to install or adapt.</item> <item>Codex setup steps plus manual fallback.</item> <item>Other runtime setup notes where known.</item> <item>Required AGENT AUTOMATION READY receipt after install and smoke test.</item> </include> <privacy> Keep org charts, brand guides, customer context, secrets, account details, and private skill bodies inside this private issue or local runtime context. </privacy>
<task> Run one Open Engine queue check for this operator. </task> <order> <step>Identify this runtime's agent code.</step> <step>Open the status ledger issue.</step> <step>Find this agent's top-level AGENT STATUS comment.</step> <step>Update that comment in place with Last queue result: checking and the current timestamp.</step> <step>Run standing context preflight before new task work.</step> <step>Check AGENT HUMAN HOLD issues before new task work. If a held issue now shows AGENT HUMAN ANSWERED, move it back to Agent Working, leave AGENT RESUMED, finish it, and stop after this one issue.</step> <step>Check AGENT BLOCKED issues before new task work. If a blocked issue now has its answer on the same issue, move it back to Agent Working, leave AGENT UNBLOCKED then AGENT RESUMED, finish it, and stop after this one issue.</step> <step>Check delegated issues this agent routed to someone else.</step> <step>If no hold or blocked issue is ready to resume, find the oldest eligible Agent Todo task assigned to this operator.</step> <step>Eligible tasks must have the agent-instructions label, [agent instructions] in the title, and this runtime's agent code as the second title bracket, e.g. [agent instructions][alex-codex][task].</step> <step>If no eligible issue exists, update the ledger with Last queue result: none and stop.</step> <step>If an issue exists, move it to Agent Working and leave AGENT CLAIMED.</step> <step>Re-read the issue after claiming.</step> <step>Do only the scoped work.</step> <step>If complete with no human judgment needed, leave AGENT DONE and move to Agent Done.</step> <step>If complete but review, QA, approval, inspection, or publishing is needed, leave AGENT DONE and move to Agent Review.</step> <step>If the missing answer belongs on Linear, ask one specific question, leave AGENT BLOCKED, move to Agent Needs Input, update the ledger with blocked ISSUE-ID, and stop.</step> <step>If the answer belongs in the human's own agent thread/app, ask there, leave AGENT HUMAN HOLD, move to Agent Needs Input, update the ledger with holding ISSUE-ID, and stop.</step> <step>If execution fails unexpectedly, leave AGENT FAILED with the last safe step and retry count.</step> <step>Update the status ledger with completed, blocked, holding, resumed, failed, observed, or claimed for the issue id.</step> <step>Stop after exactly one task issue.</step> </order> <receipts> Use AGENT CLAIMED before work, AGENT DONE when complete, AGENT BLOCKED for Linear-answerable blockers, AGENT HUMAN HOLD for owner-thread permissions, AGENT UNBLOCKED then AGENT RESUMED when a blocked issue's answer arrives, AGENT HUMAN ANSWERED then AGENT RESUMED when a hold is answered, and AGENT FAILED only for unrecoverable failure. </receipts> <boundaries> Never publish, email, Slack-post, deploy, delete, change billing, change credentials, or make outward-facing changes unless the issue explicitly grants that approval. </boundaries>
<task_issue> <title>[agent instructions][<agent-code>][task] <outcome></title> <label>agent-instructions</label> <status>Agent Todo</status> <assignee>The human/operator whose local agent should execute the ticket.</assignee> </task_issue> <body> <requester>Who is asking and how to follow up.</requester> <desired_outcome>The concrete result wanted.</desired_outcome> <context>Why this matters and what background is needed.</context> <sources>Links, files, issue IDs, docs, or none.</sources> <do>Step-by-step work instructions.</do> <acceptance_criteria>Observable success conditions.</acceptance_criteria> <output_handoff>Where to put the answer, artifact, pull request, comment, or status update.</output_handoff> <boundaries>What the agent may do, what needs approval, and what is out of scope.</boundaries> </body>
AGENT STATUS Agent: <agent-code> Human/operator: <name or unknown> Runtime: <Codex | Claude | Grok | other> Automation: <automation name or manual> Automation state: <installed | manual-required | blocked | paused> Last heartbeat: <ISO8601 timestamp> Last queue result: <checking | none | observed ISSUE-123 | claimed ISSUE-123 | completed ISSUE-123 | blocked ISSUE-123 | holding ISSUE-123 | resumed ISSUE-123 | failed ISSUE-123> Last successful run: <ISO8601 timestamp or unknown> Local context: <engine version>; <routing map version> Notes: <none or short blocker>
12 / Troubleshooting
Most Open Engine failures are routing failures, stale runner instructions, unclear human-input semantics, or missing status transitions. Fix the contract, then rerun the smoke test.
Check assignee, agent-instructions label, Agent Todo status, the [agent instructions] title marker, and that the second title bracket matches this runtime's agent code.
Move status to Agent Working before task work, leave AGENT CLAIMED, then re-read the issue. That status move is the visible lock. If two of your own runtimes share one operator, also scope pickup by the agent-code bracket so only the intended runtime claims each task.
Find the top-level AGENT STATUS comment for the current agent code and update it in place by comment id.
Treat AGENT BLOCKED as a pause. Look for the same-issue answer, then leave AGENT UNBLOCKED and AGENT RESUMED.
Use AGENT HUMAN HOLD. Ask in the human's own agent thread or app, keep the Linear issue in Agent Needs Input, and set the ledger to holding ISSUE-ID.
Use one standing issue per context family. Update the version and changelog in place; agents compare versions during preflight.
Assign the issue to the human who owns the target agent, then check the routing map, target heartbeat, label, title marker, and status.
Add explicit ask-first boundaries to the private context and task body. External or destructive actions require issue-level approval.