The readers of this page are the agent of a ticket, and the orchestrator for the plain-form rule and the tool-block rule.
This rule applies to each tasker command that the agent runs and that changes a task. Examples are start, plan, refine, approve, execute, verify, review, dismiss-review, accept, merge, finish, update-branch, retry and resume. The agent runs each such command alone in its own Bash call (one call of the Bash tool of the agent). The call has the plain form: tasker <command> <issue> and the options of the command, for example tasker accept codeguru42/tasker#81. The issue key has no quotes. No cd comes before the command, no pipe comes after it, and no other command is in the same call. A feedback text goes in as one argument, as in tasker refine <issue> "<feedback>". Inside double quotes, the shell expands backticks and $. Put the feedback text in single quotes, or keep backticks and $ out of it. For feedback text from a file, the one allowed form is tasker refine <issue> "$(cat <absolute path of the file>)". tasker review <issue> "<feedback>" takes the same form. No other command substitution is allowed. The shell does not expand backticks or $ in the text of the file. As a result, the warning above covers only the text on the command line.
The reason: the repo file .claude/settings.json allows Bash(tasker *). A Bash call matches this permission rule only when the call is one tasker command. Claude Code sends a call that does not match to the classifier of its auto mode (the check that allows or denies a tool call). The classifier can deny the call. For example, the classifier denied tasker accept 'codeguru42/tasker#81' 2>&1 | tail -5, but it allowed tasker accept codeguru42/tasker#81. On 2026-10-17, the agent of #229 ran tasker refine with feedback text from a file in the allowed form, in auto mode, and the call ran.
If the classifier denies a tasker command in the plain form, the agent does not try another form. The agent follows the tool-block rule. The command did not run.
The plain-form rule does not cover these:
- A read-only
taskercommand, which does not change a task. Examples aretasker show,tasker status,tasker show-plan,tasker show-review,tasker show-quotaandtasker doctor. Such a command can have a pipe, for exampletasker show-quota | jqin "Quota". - A change to
.claude/settings.json. The rule does not change the permission rules of the repo.
A tool block is a denial of a tool call. The permission rules, the classifier of auto mode or the user can deny a call. The user denies a call when the user declines it at a permission prompt. In past sessions, the classifier of auto mode denied gh auth token and a claude -p run. The classifier also denied a Bash call with a loop of gh issue edit <number> --add-blocked-by <issue> over the open issues two times. Both denials gave the reason "External System Writes". The second call had an explicit list of 46 numbers.
An agent runs a git command in the local clone of the orchestrator with git -C <clone>, not with cd <clone> && git ... in a chain. On #274, the classifier of auto mode denied cd <clone> && git fetch -q origin && git diff ... with the reason "[Modify Shared Resources]". A plain git -C <clone> fetch --multiple tasker origin ran with no denial.
A denial covers the whole action of the call, not only its form. After a tool block, the agent runs the denied action in no other form, and no part of it, until the orchestrator sends the answer. Other forms include a script file with the same commands, a split of the action into several calls, and the same commands with other paths or names. On 2026-10-17, the user declined a fact test with rm -rf, and the agent of #231 ran it from two script files before the answer came.
After a tool block, the agent stops. It reports the exact text of the denial, the exact command, the step of the work that the command belongs to, and the purpose of the command. The orchestrator tells the user these facts. The orchestrator does not run the blocked action for the agent, unless the user tells it to.
These rules apply to each tasker command that the agent runs, also to a read-only one. They add to the plain-form rule and do not change it.
- Give the full issue key, for example
codeguru42/tasker#90. A bare number such as90fails withno repo configured for 90, for example intasker show 90.tasker status --issue 90does not fail. It printsno tasks match the given filtersand exits with 0, so a check with a bare number finds no task. - Never wrap a
taskercommand intimeout. At the end of the time,timeoutsends SIGTERM, and tasker moves the task tointerrupted. On 2026-10-13,timeout 595 tasker executestopped an execute run this way, andtasker resumehad to continue it. - Run a long
taskercommand in the background. The long commands includeplan,refine,execute,reviewandresume. The agent sets therun_in_backgroundoption of its Bash tool. The call keeps the plain form. - To wait for the end of a long command, wait for the report of the Bash tool that the background job of the command ended. Do not wait with a loop that reads the state in
tasker status. Such a loop is not reliable. For example, a review run can end inawaiting_work_reviewor inreviewed, so a loop that waits while the state isreviewingcannot tell the end from the start. The Bash tool gives its report after a Bash call of the agent ends. While the agent waits, it runs a short wait in another Bash call, for exampletimeout 100 bash -c 'while :; do sleep 15; done'. This call always exits with 124. If no report came, the agent runs the same wait again. After the report, the agent reads the state withtasker show <issue>. When the orchestrator starts the agent again, the agent follows "What the agent does" in "Quota". - When the output of a read-only
taskercommand goes into a pipe, start the call withset -o pipefail. As a result, a failedtaskercommand stops the chain. To keep only some lines, usesed -n, for examplesed -n '1,20p', nothead. Withpipefail,headcan make the pipe exit with 141 when tasker succeeded, becauseheadstops reading early.
tasker plancan fail with "planning returned no structured output; the assistant produced no plan object". The task goes tofailed. This failure does not come from the code. Onetasker retry <issue>plans again.- When the login of the Claude account expires during
tasker execute, the execute session ends.tasker executethen fails withexecuting todo '<todo>' ... failed: claude exited 1. The task goes tofailed, and the task branch is unchanged. This failure does not come from the code. After the user logs in to Claude again,tasker retry <issue>moves the task toapprovedand runstasker executeagain. On #273, on 2026-10-17, the retry ran the same plan with no loss. tasker startcan wait about 10 minutes ongit ls-remoteover ssh and then fail with a git transport error. Iftasker doctorthen passes, the agent runstasker startagain.tasker update-branchprintsorigin/<branch> does not exist; nothing to sync fromfor a task branch that was never pushed. This output is normal.tasker dismiss-reviewprintsdismissed review findings for <issue key>. This output is normal. It differs from the output that skills/tasker/references/work-review.md gives for thetasker dismiss-reviewof this repo.tasker mergeprintslanded: <commit> on origin/main.tasker finishprints that it marked the issue done on the tracker, and it closes the issue.tasker startcan print a GraphQL warning that the assign of the issue on the tracker failed. The warning does no harm.tasker startrefuses a ticket whose parent is not ready to stack. It exits with 1 and prints<parent issue key>: blocking issue is still open. No task exists after the refusal.tasker verifyrefuses a stacked task whose parent has landed. It printstask <id>'s parent <parent issue key> has landed on origin/main; run tasker update-branch <issue key> to move this task onto it first. The task stays inexecuted.tasker update-branchrebases only the commits of the task onto the base of the parent.- A stacked task in
awaiting_plan_reviewloses its base whentasker finishof the parent deletes the branch of the parent.tasker refinethen fails with exit code 1 and anunknown revisionerror ofgit diff, and it changes nothing.tasker update-branchmoves the task onto the base of the parent, and the task stays inawaiting_plan_review. tasker marks the plan as stale, so a refine comes beforetasker approve, also when the new base changes no fact of the plan. tasker update-branch <issue> --take-remoteof a stacked task whose parent landed moves the base of the task to the base of the parent, for examplebase branch: main, and the task toexecuted, in one run.- If a task is stacked on the same parent as another task, the shared-file warning of
tasker refineandtasker approvefor that task lists the files of the parent too. The warning reads the files that the branch of the other task changes against the base, and that branch holds the commits of the parent. tasker update-branchprints the command that undoes the update after each update that moves the task branch, also with--take-remote. The output givesprevious HEAD was <hash>, and the command istasker update-branch <issue> --undo. On #252, each plaintasker update-branchprinted this hint.- When the rebase of
tasker update-branchstops with a conflict, the output names each conflicting path.
An agent picks the wait for a long command (see the wait bullet of the command rules) from these usual run times. The times come from the tickets of this repo.
tasker start: a few seconds. For the wait of about 10 minutes on ssh, see the facts of the installed tasker.tasker plan: about 1 to 2 minutes for a small issue, and about 4 to 6 minutes for a large issue.tasker refine: about 1 to 4 minutes.tasker execute: about 1 to 2 minutes for 2 to 4 todos, and about 8 to 15 minutes for 20 to 30 todos.tasker verify(npm run check): seconds.tasker review: about 25 seconds to 2 minutes.- A docs ticket: about 1 to 2 minutes for each of plan, refine and execute.