Skip to content

Latest commit

 

History

History
223 lines (191 loc) · 18.2 KB

tasker-commands.md

File metadata and controls

223 lines (191 loc) · 18.2 KB

Tasker commands

The readers of this page are the agent of a ticket, and the orchestrator for the plain-form rule and the tool-block rule. The planner and the operator also read the tool-block rule.

The plain-form 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 tasker command, which does not change a task. Examples are tasker show, tasker status, tasker show-plan, tasker show-review, tasker show-quota and tasker doctor. Such a command can have a pipe, for example tasker show-quota | jq in "Quota".
  • A change to .claude/settings.json. The rule does not change the permission rules of the repo.

The tool-block rule

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. The recommendation mode of A decision of the user does not cover a tool block: the orchestrator always waits for the user.

The classifier of auto mode can deny a gh write of a follow-up planner or an orchestrator. That session sends the operator an item with the exact command, the folder and the exact text of the denial. The operator gives the user the exact command and the folder, with the ! prefix of Claude Code.

The message of the operator to that session gives the output of the command, or says that the command did not run. The output goes with the words of the user, and this paragraph wins over The answer. If the command ran, the session goes on with its work. If it did not run, the step stays open, and the session runs the action in no other form.

An initial planner gives the user the command directly. A check failure keeps its own bullets. On 2026-10-30, the classifier denied gh issue comment and gh issue edit of planner-m26, and the user ran each command.

A check failure is a denial whose text says that the classifier of auto mode gave no verdict. A check failure is a tool block, with these differences:

  • After a check failure, the agent runs the same call again one time, in the same form. The text of the failure permits this one try. For a check failure, this one try wins over the paragraph that starts "A denial covers the whole action" and over the stop of the paragraph that starts "After a tool block". Apart from this one try, the agent runs the action in no other form, and no part of it, as the paragraph that starts "A denial covers the whole action" says.
  • If the second try runs, the agent continues its work. If the second try also fails with a check failure, the agent stops, as the paragraph that starts "After a tool block" says. In its report, the agent also says that the denial is a check failure. If the second try gets a denial that is not a check failure, that denial is a tool block with none of these differences.
  • For a check failure, the orchestrator tells the user the exact command and the link https://status.claude.com/. The agent also gives the folder where the call ran, and the orchestrator tells the user that folder. The user can run the command with the ! prefix of Claude Code, which does not go through the classifier. If the user runs the command, the orchestrator tells the agent in its answer that the command ran, with its output.
  • The orchestrator follows the same steps for a check failure of its own call: it runs the same call again one time, in the same form. If that try also fails with a check failure, the orchestrator tells the user the exact command and the link, so that the user can run the command with the ! prefix.
  • A planner follows the same steps for a check failure of its own call. If the second try also fails with a check failure, a follow-up planner sends the operator an item. The paragraph that starts "The classifier of auto mode can deny" and the paragraph after it give the steps of the item. The item also gives the link, and the operator gives the user the link. An initial planner gives the user the command and the link directly.

On 2026-10-25, in the session of #428, each Bash call that no permission rule allowed failed with this text:

The server-side auto mode classifier gave no verdict (error), so auto mode cannot determine the safety of Bash. This is a transient failure of the check, not a judgment about the action: a later response may get a verdict. You may try the action again once, as-is. Repeated attempts are slowed by a growing delay, and after 10 responses in a row without a verdict the turn stops.

The user saw "auto mode check unavailable" and "bash denied by auto mode". The calls included read-only commands, for example git show origin/main:<path> and gh issue list. At the same time, https://status.claude.com/ showed the incident "Elevated errors for Claude Sonnet 5.5" from 06:14 UTC, and Claude Code in "Partial Outage". No incident named auto mode. The user then ran gh issue create with the ! prefix, and the posts of #482 and #483 worked.

The command rules

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 as 90 fails with no repo configured for 90, for example in tasker show 90. tasker status --issue 90 does not fail. It prints no tasks match the given filters and exits with 0, so a check with a bare number finds no task.
  • Never wrap a tasker command in timeout. At the end of the time, timeout sends SIGTERM, and tasker moves the task to interrupted. On 2026-10-13, timeout 595 tasker execute stopped an execute run this way, and tasker resume had to continue it.
  • Run a long tasker command in the background. The long commands include plan, refine, execute, verify, review and resume. The agent sets the run_in_background option 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 in awaiting_work_review or in reviewed, so a loop that waits while the state is reviewing cannot 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 example timeout 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 with tasker 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 tasker command goes into a pipe, start the call with set -o pipefail. As a result, a failed tasker command stops the chain. To keep only some lines, use sed -n, for example sed -n '1,20p', not head. With pipefail, head can make the pipe exit with 141 when tasker succeeded, because head stops reading early.

The facts of the installed tasker

The installed tasker is a build of this repo, as the intro of docs/orchestrator.md says. tasker --version prints the version of the build. The intro of docs/dev/release.md gives the forms of the version.

Each fact of this page that names the installed tasker, for example each fact of this section, describes a behavior of the installed tasker. The fact is not a requirement for later work. If a ticket depends on such a fact, the agent first does the fact test against the installed tasker. The reason, in the words of the user: "We need to verify that the tasker behavior we are changing actually exists before trying to change it."

The fact test can show that the installed tasker does not have the behavior. Then the fact is out of date. The agent gives the fact, the command and the output in the feedback text and in the lessons of its final report. The lesson goes to the planner, and the planner files a ticket for the fact. If an open issue already covers an out-of-date fact, the agent names that issue in place of the lesson.

The agent cannot always measure such a behavior, for example when no task of its own is in the state that the fact needs. Then the agent reports the fact as a fact that it cannot test, in the feedback text and in its final report. A ticket that only records such a fact does no fact test, as the user decided for #366. Such a ticket depends on no fact of the list. As a result, the rule that the agent first does the fact test does not apply to it.

  • tasker plan can fail with "planning returned no structured output; the assistant produced no plan object". The task goes to failed. This failure does not come from the code. One tasker retry <issue> plans again.
  • When the login of the Claude account expires during tasker execute, the execute session ends. tasker execute then fails with executing todo '<todo>' ... failed: claude exited 1. The task goes to failed, 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 to approved and runs tasker execute again. On #273, on 2026-10-17, the retry ran the same plan with no loss.
  • tasker start can wait about 10 minutes on git ls-remote over ssh and then fail with a git transport error. If tasker doctor then passes, the agent runs tasker start again.
  • tasker update-branch prints origin/<branch> does not exist; nothing to sync from for a task branch that was never pushed. This output is normal.
  • tasker dismiss-review prints dismissed findings <positions> of review <number> of <issue key>. This output is normal.
  • tasker merge prints landed: <commit> on origin/main. tasker finish prints that it marked the issue done on the tracker, and it closes the issue.
  • tasker start can print a GraphQL warning that the assign of the issue on the tracker failed. The warning does no harm.
  • tasker start refuses 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 refine, tasker execute, tasker verify, tasker review and tasker accept refuse a stacked task whose parent has landed. They print the parent <parent key> of <issue key> has landed; run tasker update-branch <issue key> to move the task onto <base that the walk ends on> first. The task keeps its state. tasker merge and tasker mark-landed print the same error, and they print the parent <parent key> of <issue key> has not landed; land the parent first, then run tasker update-branch <issue key> while the parent is in flight (see the stacked-task guards). tasker update-branch rebases only the commits of the task onto the base that the walk ends on.
  • A stacked task in awaiting_plan_review loses its base when tasker finish of the parent deletes the branch of the parent. tasker refine then fails with exit code 1 and the landed error of the moved-base guard, and it changes nothing. tasker update-branch moves the task onto the base that the walk ends on, and the task stays in awaiting_plan_review. tasker marks the plan as stale, so a refine comes before tasker approve, also when the new base changes no fact of the plan.
  • A task can fail in executing while its base is main and its task branch holds no commit of the task. For such a task, tasker update-branch moves the task branch by fast-forward. The approved plan of such a task stays approved, and the task stays in failed. After the update, tasker show prints next: tasker retry. On #413, on 2026-10-25, the installed tasker 2026.10.25-60b6aa03 moved the task branch from 9d10f960 to 60b6aa03, and plan v2 stayed approved.
  • tasker update-branch <issue> --take-remote of a stacked task whose parent landed moves the base of the task to the base that the walk ends on, for example base: main, and the task to executed, in one run.
  • If a task is stacked on the same parent as another task, the shared-file warning of tasker refine and tasker approve for 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-branch prints the command that undoes the update after each run that moved the head, also with --strategy or --take-remote. A run moved the head when its base step or its sync step moved it. The output gives previous HEAD was <hash>, and the command is tasker update-branch <issue> --undo. On #252, each plain tasker update-branch printed this hint.
  • When the rebase of tasker update-branch stops with a conflict, the output names each conflicting path.
  • After tasker update-branch, the bootstrap of the task does not run again. If the new base changes package-lock.json, tasker verify fails on the old node_modules of the worktree of tasker. The fix is a refine that tells the execute session to run npm ci. On #119, on 2026-10-18, a parked task moved from b90d814 to 5e4be61, and tasker verify failed with ERR_MODULE_NOT_FOUND for eslint-config-prettier. For the verify-failure rule, this failure comes from the code. The agent sends one refine whose feedback tells the execute session to run npm ci, and it runs no tasker retry. A commit check that finds no broken commit does not change this case.

The run times

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): more than 2 minutes on a local run. On #508 (2026-11-01), a local run passed the default limit of one Bash call. In the Check workflow, the same command takes about 3 to 4 minutes.
  • tasker review: about 25 seconds to 2 minutes.
  • A docs ticket: about 1 to 2 minutes for each of plan, refine and execute.