The readers of this page are the orchestrator and the task subagents.
These limits apply to the orchestrator and to the task subagents, except where a bullet or a rule names one actor.
-
The task subagent reads the output of a task with the
tasker showcommands, for exampletasker show,tasker show-plan,tasker show-verifyandtasker show-review. The own-worktree rule gives the rule for a direct read of a file of the data folder of tasker, for example a transcript or a log file. -
To read the commits of a task branch, the task subagent runs
git fetch taskerin the local clone of the orchestrator. If the clone has notaskerremote, the task subagent adds it as the own-worktree rule says. Then the task subagent runsgit logorgit showontasker/<task branch>. For a diff of the task, the task subagent uses the command with three dots of the diff read. In a split read, the task subagent also usesgit diff <commit>~1 <commit>for each commit of the range. If a command fails, the task subagent stops and reports the error. Nothing changes. -
If a
git fetchof a task subagent fails, also after atimeout(exit code 124), and its step gives no failure path, the task subagent runs the fetch one more time. If the fetch fails again, the task subagent stops and reports the command and the error. A step that gives its own failure path keeps it. -
The task subagent installs dependencies in its local task worktree only before a direct npm script or test there. A
taskercommand alone requires no dependency install in that worktree. Examples aretasker execute,tasker verifyandtasker review. The local task worktree is the worktree of the own-worktree rule, not a worktree of tasker.Before each direct npm script or test there, the task subagent applies both install cases below. If the worktree has no
node_modules, the task subagent runsnpm cithere. Ifpackage-lock.jsondiffers from the copy of the last install, the task subagent runsnpm cithere. Examples arenpm run check,npm run format:checkand the test loop of the measure rule. On #400,npm run format:checkfailed in a new task worktree withprettier: not founduntilnpm ciran. Use the copy of the commit check:L=$(git rev-parse --git-path npm-ci-lock); cmp -s "$L" package-lock.json || { npm ci && cp package-lock.json "$L"; }. -
The task subagent uses only the issue, the files of the repo, its own tests on the local machine and the answers of the orchestrator as sources. If the issue does not give a detail that the work needs, the task subagent asks the orchestrator. Then the task subagent waits for the answer, as the answer-wait rule says. Before
tasker approve, the stop rule and the design-gap rule give the steps and say who answers. Aftertasker approve, the orchestrator asks the user. When the task subagent asks the orchestrator a question, the task subagent gives the options, with its suggestion for each. -
The task subagent changes only its own issue. On GitHub issues, labels and the project board, the comment of step 11 of "Run one ticket" is the only write of the task subagent. The task subagent does not edit an issue body, a label or the project board. This rule does not cover the git commands and the
taskercommands of the steps on the orchestration pages, for exampletasker mergeand the delete of the task branch in step 10. On GitHub Actions, the rerun of step 9 of the CI wait (gh run rerun <run id> --failed) is the only write of the task subagent. -
If tasker stops for a quota, follow "Quota". Never run
tasker approve-credits. -
Do not install
taskerfrom a task worktree, also not withnpm link. Installtaskerwithnpm run install:global, as the Install section of README.md says. The install runs in the current clone, on the commit that is checked out. The installedtaskerruns the tickets, and an install replaces it. -
No session writes memory, as the memory rule says. A task subagent also deletes no memory note, so that two task subagents do not change the same file. Task subagents report what they learn to the orchestrator in their final report (see the final report). A task subagent does not run
/session-review, because the skill deletes memory notes. The bullet "When the final report of the task subagent of a ticket says that the ticket landed" of Land the work says when the orchestrator deletes a note. -
The orchestrator and each task subagent load the simple-english skill and follow the simple-english bullet of Docs of rules.md.
-
The folder of a task subagent is
$HOME/Documents/tasker/agents/<session name>. The session name is the name of the session of the task subagent from "The prompt of a task subagent", for examplecodeguru42-tasker-43. The task worktree of the own-worktree rule is../tasker-worktrees/<session name>, relative to the root of the local clone of the orchestrator. That path is a folder with the session name in the foldertasker-worktrees, next to the local clone of the orchestrator. The task worktree is not in the folder of the task subagent and not in the clone. The orchestrator makes the folder of the task subagent before the task subagent starts, as "The prompt of a task subagent" says. The task subagent keeps each other file that it writes in the folder of the task subagent, for example the feedback files and the notes. Two task subagents that run at the same time keep their files in different folders. The task subagent does not write a file in the scratchpad folder that Claude Code names in the system prompt of the task subagent. The reason: each task subagent of one orchestrator gets the same scratchpad folder as the orchestrator. This rule wins over the instruction of the system prompt of the task subagent to use the scratchpad folder for temporary files. For example, on #519 (2026-10-25), the task subagent wrote two files in the scratchpad folder and then moved them to the folder of the task subagent. It overwrote nothing. Before a task subagent runstasker refineortasker review <issue> "<feedback>"with feedback text from a file, the task subagent makes sure that the file holds the text for its own ticket. The plain-form rule gives the form of the command. If two task subagents use the same file name, the refine or the review of one ticket can send the text of another ticket. The folder of the task subagent stays after the work. The task subagent removes only the task worktree, as the own-worktree rule says. -
If a
gh issue,gh labelorgh runcommand runs outside a git repo with no-Rflag and no issue URL, it fails. The error holdsfatal: not a git repository. The folder of a task subagent is outside a git repo. As a result, the task subagent adds-R <owner>/<repo>to each such command that it runs in its folder.<owner>/<repo>is theowner/repopart of the issue key of the ticket. -
Do not use
pkillorkillall. To stop a process that it started, the orchestrator or the task subagent useskillwith the process id that it saved.pkillmatches by name, so it can stop a process of another session of the same user. -
Never print a credential, for example an access token, a password or a key. If a command gives a credential, store its output in a shell variable, for example
token="$(gh auth token --hostname github.com --user <account>)". Do not print the variable. To make sure that the command succeeded, use its exit code or a test of the variable that prints nothing, for example[ -n "$token" ]. Pass the variable to later commands, for exampleGH_TOKEN="$token" gh api user. Do not put the credential itself in a command line, a file, a log, a feedback text or a comment. Never print the environment, for example withenv,printenvorset, because it can hold a credential, for example the access token inGH_TOKEN. The assistant tools start a new shell for each tool call, and a shell variable lives only in its own shell. As a result, set the variable and use it in the same tool call. Never print the full command line of the sandbox, for example withps -o args. The sandbox of aclauderun is abwrapprocess. Its command line holds a user name and a password of the local proxy of that run. On 2026-10-14, a task subagent printed them in its tool output withps. To find a bind or a path in the command line, search it for only that item, and print only the match. For example,ps -o args= -p <pid> | grep -o -F -- '<path>'prints only<path>, and only when the command line holds it. This rule does not cover the code of tasker, which already keeps the access token out of its errors and logs. -
The issue-link rule is in docs/dev/working-with-the-user.md.
The orchestrator and the task subagents must not read the files that tasker keeps in its data folder. Never read, search
or run anything in a worktree of tasker, also not with a read-only command such as grep. Do not change the repo or the
worktrees of tasker by hand. Only tasker commands change them. The read has two exceptions. The first exception is a
fetch through the read-only tasker remote, which reads the clone of tasker and changes nothing there. The second
exception is a read that the user permits. A read of a file of the data folder, for example the database tasker.db, a
log or an archived prompt, is allowed only when the user permits that read. The second exception does not cover a
worktree of tasker. Before the read, the orchestrator asks the user, with the fact that it needs and the command that it
plans. A task subagent asks the orchestrator, as the sources bullet of Limits says, and the orchestrator then
asks the user. For a task subagent, the orchestrator does the read and gives the fact to the task subagent as an answer.
Without that permission, the tasker commands are the only way to read the state of a task. For a task subagent, the
first bullet of Limits names these commands. The reason: a tasker command does not give every fact, for
example the time of an event, and a direct read without permission is a read of data that the user owns. On 2026-10-17,
an orchestrator read event times from tasker.db with sqlite3 -readonly, and the user said: "you need to ask
permission before accessing any tasker resources". tasker show <issue> prints the worktree of the task on its
worktree: line, and the rule of this paragraph covers that worktree.
To read or run the code of a task, the task subagent uses its task worktree. The task worktree is the one worktree of a
task subagent for its task. It is a worktree of the local clone of the orchestrator, in the folder that the folder
bullet of Limits gives for the task worktree. It is on a local branch with the same name as the task branch.
The task branch is on the branch: line of tasker show <issue>.
- Make: the task subagent makes the task worktree one time, after
tasker startin step 2 of "Run one ticket" or in the comeback rule. If the local clone has notaskerremote, add it as steps 1 and 2 of the remote setup say. Then rungit fetch tasker. If the fetch fails, stop. Nothing changes. Then rungit worktree add -b <task branch> <path> tasker/<task branch>. If it fails for a reason other than the branch-exists case, stop. No worktree exists. - The path: the task subagent keeps
<path>from the make until the remove at the end. The task subagent keeps<path>as an absolute path, because git resolves a relative path against the current folder of each command. Each later step uses that path. This includes the<path>of steps 6, 18 and 19 of rebase-conflicts.md. - Use: each step that reads or runs the code of the task uses the task worktree, after the update rule.
- The branch-exists case: the make fails with
fatal: a branch named '<task branch>' already existsand exit 255. Git makes no folder. The local branch can hold commits that tasker does not hold, for example after a stop of the manual fix. Do these steps before the first update:- Read
<hash>withgit rev-parse --verify tasker/<task branch>. Then rungit merge-base --is-ancestor <task branch> <hash>. - If the exit code is 1, the local branch holds a commit that tasker does not hold, or tasker rewrote the task branch after the last update, for example with a rebase or an autosquash. The step cannot tell the two apart. Stop. The branch and each worktree of the branch stay.
- If the exit code is neither 0 nor 1, or a command fails, stop.
- If the exit code is 0, run
git worktree list --porcelain. If an entry has the linebranch refs/heads/<task branch>, use theworktree <path>line of that entry as the task worktree. - If no entry has that line, run
git worktree add <path> <task branch>, with no-band no--detach. For a branch that no worktree holds, this makes a worktree on the branch. - Then do the update rule.
- Read
- The remove: the task subagent removes the task worktree only at the end of its work. The end is after step 10 of "Run
one ticket", after
tasker abort, or when the orchestrator tells the task subagent to end its work. Rungit worktree remove <path>. Do not use--force. If the remove fails, stop, as step 19 of rebase-conflicts.md says. The worktree and the local task branch stay. Then delete the local task branch withgit branch -D <task branch>. If the delete fails, stop. The worktree is gone, and the local task branch stays. The orchestrator reports to the user. - Exceptions to the remove: if the task subagent followed rebase-conflicts.md, steps 18 to 20 of that page do the remove. The task subagent does not do it again. While the local-commit rule holds, the worktree and the local branch stay. They also stay after a step of rebase-conflicts.md stops. The final report names each path that stays.
- Worktree commands change no task. The task keeps its state.
tasker changes the task branch in its own clone, for example with tasker execute, tasker refine and
tasker update-branch. The task worktree does not follow by itself. Before each use, the task subagent does these steps
in the task worktree:
- Run
git fetch tasker. - Read
<hash>withgit rev-parse --verify tasker/<task branch>. The hash lives only for this update. - Run
git rev-parse --git-path rebase-merge. If the command fails, or the folder that it names exists, stop. Nothing changes. Then rungit rev-parse --git-path BISECT_START. Make sure that the command succeeds and its named file does not exist. If either condition fails, stop without reset or cleanup. Nothing changes. For example, the worktree stays in a rebase whengit rebase --abortfails in step 7 of the commit check. - Run
git status --porcelain. If it prints a line, stop. Nothing changes. Test the output, because the command exits with 0 also when it prints lines. Ignored files such asnode_modules/do not print. - Run
git reset --keep <hash>.
git reset --keep moves the branch for a fast-forward. It also moves a branch that a rebase of tasker rewrote, where
git merge --ff-only fails with exit 128. For a change in a file that the update changes, --keep refuses with exit
128 (error: Entry '<file>' not uptodate. Cannot merge.), and the branch and the change stay. Step 4 already stops for
each uncommitted change. As a result, no update runs over one. Do not use --hard, because it deletes changes that are
not committed. If a step fails, the step that uses the worktree gives the failure path. The commands of the update rule
change no task.
The local task branch holds no commit of its own, with two exceptions. The first is
the manual fix, from its step 2 to step 11 of rebase-conflicts.md. The second is
rebase-conflicts.md after a rebase conflict of tasker update-branch, from step 7 (the rebase) to step 11
(--take-remote). In that time, the task subagent does not run the update rule. If the task subagent
stops in that time, for example after a failed push at step 10, the worktree and the local
branch stay. The rule ends at each step 11 of docs/dev/rebase-conflicts.md, except at
the new conflict of that step. At that new conflict, the rule holds with no break through the loop of that step. After
each other step 11 of that page, tasker holds the local tip (<taken>), and the rule
ends. The manual fix and rebase-conflicts.md link to this rule.
Every orchestrator and every task subagent on the machine run git in one local clone. As a result, a git command of any
session, for example git fetch, can run between two commands of a step. On 2026-10-15, git worktree list in the
local clone listed the worktrees of the task subagents of other orchestrator sessions. A remote-tracking ref is the copy
of a branch of a remote in the local clone, for example origin/<branch> or tasker/<branch>. If a step uses a
remote-tracking ref in more than one command, the step reads the full hash of the ref one time, with
git rev-parse --verify <ref>. Each later command of the step uses that hash, not the ref. For example, if step 10 of
"Run one ticket" read origin/<task branch> for the check and again for the delete,
a fetch between the two reads can move the ref, and the delete then acts on a commit that the check did not see. Use
--verify, because plain git rev-parse also prints the name on its output when it fails. If git rev-parse --verify
fails, for example because the ref does not exist, it exits with 128 and prints fatal: Needed a single revision. The
step then stops, as the failure cases of that step say. If a step uses a remote-tracking ref in only one command, the
step needs no hash read. The update rule reads tasker/<task branch> one time and resets to that hash.
The task subagent sends each message to the orchestrator with SendMessage and to: "main". The task subagent puts
"main" in the to option of SendMessage, not in the text of the message. The session name of the orchestrator, for
example orchestrator-m8, is not the address. The rule covers each message that the task subagent sends while it works.
Examples are the run-start and run-end reports of
"When there is no reset time yet" in "Quota", the reports
of the stop cases, the list of files after tasker approve and the questions.
The rule does not cover the final report (see the final report), except after a
refused SubagentHandback call. The task subagent of #153 learned this rule on 2026-10-15.
When the task subagent must wait for an answer or a next step from the orchestrator, the task subagent sends its report
or its question with SendMessage, as the address rule says. Then the task subagent gives its
final answer, which ends its turn. This final answer is an interim report (see
the final report). The task subagent does not wait in a loop. The message of the
orchestrator with the answer or the next step starts the task subagent again. The reason: a message to a task subagent
that has ended starts the task subagent again, and the task subagent keeps its context (see "Terms" in
"Quota"). On #153, the task subagent waited about 25 minutes in a loop for an answer, then ended its
turn with a stop report. The message with the answer started the task subagent again, and the task subagent went on with
its work.
In Claude Code 2.1.314, a subagent gives its final answer with the tool SubagentHandback. The text of the tool says
that plain text at the end of a turn does not reach the orchestrator. It also says "Use it once", "The call ends your
run" and "do not use it for progress updates or questions". The subagent still uses this tool for an interim report,
because it has no other final answer. On 2026-10-30, a SendMessage after a SubagentHandback call started a
background subagent again with its context. After this start, a second SubagentHandback call of that subagent also
reached the session that started the subagent.
A refused SubagentHandback call is a call of that tool whose result says that nothing was sent. An example of such a
result is "Nothing was sent: your report was already delivered (SubagentHandback delivers one report). Use SendMessage
for anything further, then stop." After a refused SubagentHandback call, the task subagent sends the same report with
SendMessage, as the address rule says. The message starts with a line that says that Claude Code
refused the SubagentHandback call. The report follows that line with no change. Then the task subagent ends its turn.
This send covers the final report and each interim report that the task subagent did not send with SendMessage before
the call. It does not cover a final answer that follows a report with SendMessage. An example is the final answer of a
stop. It also does not cover the interim final answer of a task subagent that stays in its wait, as
the task subagent notice says. The orchestrator takes the message of a refused
SubagentHandback call as the report of that call. If the SendMessage call fails, the task subagent ends its turn,
and the report stays only in its transcript.
Claude Code 2.1.318 refused a second SubagentHandback call after a start by the end of a background command. On #734
(2026-11-04), the task subagent gave an interim report with SubagentHandback while its background command ran, against
the wait bullet of the command rules. The end of that command started the task
subagent again, with no message of the orchestrator. Claude Code refused its next SubagentHandback call, the final
report, and the final report did not reach the orchestrator as a message.
In a test on the same day, a SendMessage started a test subagent again, and its second call reached the session that
started it. In another test on that day, the end of a background command started a test subagent again. Claude Code
refused its second call, and a SendMessage after it reached the session that started the subagent. No one measured how
often Claude Code refuses a second call, a third call, or a call after a start by another event. An example of another
event is the report of a subagent of the task subagent.
A stop of a task subagent has these parts:
- The task subagent runs no other
taskercommand until the orchestrator tells it the next step. - The task subagent sends its report with
SendMessage, as the address rule says. - The task subagent gives its final answer, which ends its turn.
- The task keeps its state.
- The message of the orchestrator with the answer or the next step starts the task subagent again.
- The step that stops names what stays behind, for example a worktree or a branch.
A step that stops gives only the facts that differ from this list, for example a state of the task that changes, what stays behind, or a report to someone other than the orchestrator. When a step of the orchestration pages sends the task subagent to docs/dev/rebase-conflicts.md, each stop of its procedure is a stop.
For a resume message during the wait, see the resume rule in "When the job fires". The rule does not cover a wait that reads a state, for example the "To wait" bullet of "Land the work" or the wait bullet of the command rules.
A wait point is a place where the task subagent waits for an answer or a next step from the orchestrator. Each stop is a wait point. At each wait point, the orchestrator expects an interim report from the task subagent. The harness is the tool that runs the task subagent. The harness can deliver the final answer of the task subagent to the orchestrator in the same way as the final report. At a wait point, the task subagent starts its interim report with a line that says that the report is not the final report. That line also names what the task subagent waits for.
The orchestrator does not treat an interim report as the end of the ticket. For an interim report alone, the orchestrator does not free the slot, delete a quota job or read the board for the ticket. The orchestrator still follows the bullets of Delete the job. The orchestrator still does each read that a rule gives after a report of a task subagent, for example in the parent-hold rule. On #160, #161 and #221, the task subagents ended their turns at a wait point, and a message of the orchestrator resumed each one.
If a command or a tool call of the orchestrator fails, the orchestrator tells the user the command, or the tool, and the error. No task changes. The orchestrator does the other steps of its rule, unless the rule says that it stops or waits.