The reader of this page is the agent of a ticket. The base rule covers each command of this page that uses origin/<base branch>.
The agent of the ticket runs steps 1 to 11. Each step gives the state of the task after its command succeeds.
- Run
tasker doctor. Then read the issue withgh issue view <number>, and compare the issue body with the prompt of the agent. If the body differs from the prompt, report each change to the orchestrator. The body can change while the agent works. Eachtaskercommand of steps 1 to 11 follows the command rules. - If
tasker status --issue <issue>already lists a task for the ticket, for example a parked task that came back (see the defer rule), follow the comeback rule instead of this step. Runtasker start <issue>. The task goes toworkspace_ready. Read the output oftasker start, also stderr. The notebased on <key>'s branchconfirms a stacked task. If the note and the prompt do not agree (the prompt names a parent and the note is missing, or the note is present and the prompt names no parent), stop. Iftasker startrefuses withblocking issue is still open, stop. No task exists. Then make the task worktree as the own-worktree rule says. If the make fails, stop. The make changes no task. Then runtasker plan <issue>. The task goes toawaiting_plan_review. - Read the plan with
tasker show-planandtasker show-questions. Compare the plan with the Requirements and the Docs sections of the issue. Then apply the stop rule and do the quote check. - If the plan needs changes, run
tasker refine <issue> "<feedback>". Add the repo-files rule to the feedback text. Before the first refine, do the fact test and the issue check. The task goes toawaiting_plan_reviewagain. Then do steps 3 and 4 again until the plan needs no changes. Put the answers to the plan questions in the feedback text.tasker plantakes no feedback. - Run
tasker approve. The task goes toapproved. Runtasker execute. The task goes toexecuted. Runtasker verify. If the verify commands pass, the task goes toawaiting_work_review. If they fail, follow the verify-failure rule. Runtasker review. When the review has findings, the task goes toreviewed. When it has none, the task stays inawaiting_work_review. If the review has no findings, go to step 9. - Read the findings with
tasker show-review. Decide for each finding if it is real. Then do the quote check. - Dismiss each finding that is not real, with a reason:
tasker dismiss-review <issue> --finding N "<reason>". The task stays inreviewedwhile a finding is still open. If you dismiss all the findings, the task goes toawaiting_work_review, and you go to step 9. - If real findings are still open, run one
tasker refine <issue> "<feedback>". It acts on all the open findings. Add the repo-files rule to the feedback text. The task goes toawaiting_plan_review. After the refine, do steps 3 and 4 for the new plan. Then do steps 5 to 8 again, starting withtasker approve. The "Review findings" section limits the number of loops. - Run each
taskercommand of this step as the plain-form rule says. The rule also covers thetaskercommands that change a task in the other steps. Before eachtasker acceptof this step, also the one aftertasker update-branch, do the diff read. Runtasker accept. The task goes toaccepted.tasker acceptrefuses when the branch does not contain the tip oforigin/main. In that case, runtasker update-branch. The task goes toexecuted. Then runtasker verifyandtasker reviewagain as in step 5. Iftasker verifyfails, follow the verify-failure rule. If that review has findings, go to step 6. Otherwise, runtasker acceptagain. Runtasker merge. The task goes tolanded. Then do the CI wait. The task stays inlanded. If the CI wait passes, runtasker finish. The task goes tofinished, and the issue closes. If a run failed, step 12 of the CI wait runstasker finish. If the CI wait stops, do not runtasker finish, and do not do steps 10 and 11. - After
tasker finish, make sure thatoriginhas no task branch of the ticket. Do not rely ontasker finishfor this. Do this step after eachtasker finish. At the end of this step, whatever its result, remove the task worktree as the own-worktree rule says. Each "then do step 11" of this step comes after that remove. The remove changes no task, and the task keeps its state, for examplefinished. In each case of this step that says "delete nothing" or "delete nothing more", report to the orchestrator, and then do step 11. In such a case, unless the case says otherwise, the task branch onorigincan still exist, and the task keeps its state. If the agent followed docs/dev/rebase-conflicts.md and did not do its steps 15 to 20 yet, it does those steps first. If a step of that page stops before step 21, do not do the rest of this step. The shared failure paragraph before step 15 of that page names what stays behind, with the difference that the step names, and the task keeps its state. Report to the orchestrator. Then do step 11. After steps 15 to 20, step 21 of that page sends the agent back to this step. The agent then does the rest of this step and does not do steps 15 to 20 again. Run each command of this step in the local clone of the orchestrator. Runtasker show <issue>. It prints the task branch on thebranch:line and the base branch on thebase branch:line. Iftasker showfails, delete nothing. Iftasker showdoes not print the linestate: finished, delete nothing. For example, the task is incleanup_failed. In each case that follows, the task stays infinished. Rungit fetch origin. If the fetch fails, delete nothing. Find out iforiginhas the task branch, with a read-only command:git ls-remote --exit-code --heads origin refs/heads/<task branch>. Give the full ref, because a short name also matches a longer branch name that ends with it. For example,xmatchesfeature/x. The command exits with 0 whenoriginhas the task branch. It exits with 2 whenorigindoes not have the task branch. It exits with 128 when git cannot reachorigin, for example when the path oforigindoes not exist. If the exit code is 2, the step is complete, and the task stays infinished. If the exit code is not 0 and not 2, delete nothing. Whileoriginhas the task branch,git fetch originupdatesorigin/<task branch>. A fetch without--prunekeepsorigin/<task branch>afterorigindeleted the branch. For this reason, the read of the tip and the next check run only after the exit code 0 ofgit ls-remote. If the exit code is 0, read the tip of the task branch onorigin:git rev-parse --verify origin/<task branch>. The command prints the full hash of 40 characters of the tip. This step calls it<commit>. If the command fails, delete nothing. Then read the tip of the base branch:git rev-parse --verify origin/<base branch>. This step calls the hash<base>. If the command fails, delete nothing. Make sure that the base branch contains<commit>:git merge-base --is-ancestor <commit> <base>. This is the ancestor check of docs/dev/rebase-conflicts.md, with<commit>as<tip>. That check gives the exit codes and the meaning of exit code 1. If the exit code is 1, do the patch check of that page, with<commit>as<tip>and the same<base>. Do only the patch check and the take check, and do not do step 17 itself or steps 18 to 21 of that page. Ifgit cherryexits with 0 and a line starts with+, and the agent followed docs/dev/rebase-conflicts.md for this task, do the take check of that page. The agent is then the operator of that page and recorded<taken>at its step 11. Use<commit>as the pushed tip, the same<base>and the landed commit thattasker mergeprinted. Use only the two facts of the take check. Step 17 of that page already compared the local tip before step 20 deleted the local task branch. If the agent did not follow that page for this task, do not do the take check. If the patch check fails and the take check does not pass, delete nothing. For example, a fact does not hold, or a command of the take check fails. The task branch onoriginstays. If the exit code is not 0 and not 1, delete nothing. The task branch onoriginstays. If the exit code is 0, or the exit code is 1 and the patch check or the take check passes, delete the task branch onoriginwith a lease:git push --force-with-lease=refs/heads/<task branch>:<commit> origin --delete <task branch>. With the lease, git deletes the branch only when the branch onoriginis still at<commit>. As a result, the delete cannot remove a commit that someone pushed to the task branch after the check. If the push succeeds, it exits with 0, and git prints- [deleted] <task branch>. The step is complete, and the task stays infinished. If the push fails, for any reason, delete nothing more. For example, if someone pushed a new commit to the task branch after the check, the push exits with 1, and git prints! [rejected] (delete) -> <task branch> (stale info). The task branch onoriginstays with the new commit. If someone deleted the branch after the check, the push exits with 1, and git printserror: unable to delete '<task branch>': remote ref does not exist. For another failure, the task branch onorigincan still exist. - After
tasker finish, post a comment on the issue that starts with## Decisions made during implementation. List the choices that the issue did not state, with the reasons. Name each detail that the issue did not give. A list item of the comment has no bold text at its start. The agent writes the comment in its final form before it posts it, because GitHub keeps the history of each edit.
At the end of its work on the ticket, the agent gives a final report to the orchestrator. The agent gives the final report as its final answer, not with SendMessage. The work of the agent on the ticket ends after step 11, or when the orchestrator tells the agent to end its work, for example in step 1 of the defer rule. A final answer that the agent gives before the end of its work is an interim report, not the final report. That final answer gives the state of the task, says if the agent stopped, and says that the agent waits. Examples are the final answer of the answer-wait rule and the end of the turn after a quota stop in "What the agent does" in "Quota". The report gives these items:
- The result: the landed commit, the number of review loops, the files that landed and, for each doc that landed, the sections that changed. If the work of the agent ended before
tasker finish, for example after the orchestrator told the agent to end its work, the result gives the state of the task and the reason for the end of the work. - Each finding that the agent dismissed, with its reason.
- The edge cases that the agent left out (see "Review findings").
- Each claim of the issue that was no longer true and each conflict (see the issue check). For a false claim, the bullet gives the current fact and the command that shows it. For a conflict, it gives the requirement, the conflicting rule or decision, the command or the doc that shows it, and the resolution: the change in the feedback text of the refine of step 4, the text of the plan that already resolves the conflict, or the answer of the user. If the task branch already held commits at the issue check, also the files that the agent read from the base commit and how. The bullet also gives each claim that the agent cannot test, because the issue names no ticket and no date for an output of the installed tasker.
- Each task worktree or local task branch that stays, with its path. The own-worktree rule says when one stays.
- The lessons.
The orchestrator sorts the lessons. A lesson that is a rule for the repo or for agents goes where the new-rule bullet of "The prompt of an agent" says.
This rule covers a ticket that already has a task in flight when its agent starts, for example a parked task that came back (see the defer rule). The task already exists, so the agent does not run tasker start or tasker plan. If the issue has a comment that starts with ## Parked task (step 6 of the defer rule), the agent reads the last such comment. Then it runs tasker show <issue>. Then the agent does the remote setup. Then the agent makes the task worktree as the own-worktree rule says. The branch-exists case can apply. The make changes no task. If the task is in quota_blocked, interrupted or awaiting_quota_approval, the agent follows "What the agent does" in "Quota", and it does not do the rest of this rule. Otherwise, the agent runs git merge-base --is-ancestor origin/<base branch> tasker/<task branch>. If the exit code is 1, the base branch moved. In that case, if tasker show <issue> lists update-branch, the agent runs tasker update-branch. If tasker show <issue> does not list update-branch, the agent does not run it. The diff read before tasker accept finds the move later. If tasker update-branch reports a rebase conflict, the agent follows docs/dev/rebase-conflicts.md, as "Land the work" says. If a step of that page stops, a command fails, or the exit code is not 0 and not 1, the agent stops. Otherwise, the agent continues "Run one ticket" from the state that tasker show <issue> prints. After tasker update-branch, "Land the work" gives the next commands for the states that it names. For another state, for example failed, the agent follows the commands that tasker show <issue> prints.
This rule covers each command of the orchestration pages that uses origin/<base branch>. A stacked task is a task that tasker start based on the branch of its parent (see the stacked-ticket rule).
Before each such command, the agent reads the base branch: line of tasker show <issue>. The agent does these steps:
- If the line has a plain name, use
origin/<base branch>as the command says. - If the line has the form
refs/heads/<parent branch>, the task is stacked. Right before the command, rungit fetch tasker. Then usetasker/<parent branch>in place oforigin/<base branch>. If the step already rangit fetch taskerorgit fetch --multiple tasker originright before the command, it needs no second fetch. - If a step uses
tasker/<parent branch>in more than one command, read its hash one time withgit rev-parse --verify, as the shared-clone rule says.
A tasker update-branch with no conflict moves a stacked task onto the base of the parent after the parent lands.
An agent of a stacked task meets a landed parent at tasker verify in executed. It also meets a landed parent at tasker refine in awaiting_plan_review, after tasker finish of the parent. The facts of the installed tasker say what happens in each case.
These steps use the base: the comeback rule, the diff read, the issue check, the broken-commit steps, the commit check, the same-patch rule, and steps 3 to 5 of docs/dev/rebase-conflicts.md when those rules do them.
Step 4 of docs/dev/rebase-conflicts.md does not stop for a stacked task when the diff read, the comeback rule or the commit check does the steps of that page. The manual fix and the procedure for a rebase conflict keep the stop.
If the task is in awaiting_work_review and the agent must add work, the agent runs tasker review <issue> "<feedback>". The agent adds the repo-files rule to the feedback text. The task reaches awaiting_work_review after a review with no findings in step 5 or step 9, or after the agent dismisses all the findings in step 7. In this state, tasker refine refuses to run. The work can come from the orchestrator, for example. After tasker review <issue> "<feedback>", the task goes to refining, and tasker makes a new plan revision. Then the task goes to awaiting_plan_review. Then the agent does steps 3 and 4 for the new plan, and steps 5 to 8 again, starting with tasker approve.
Each time before the agent runs tasker accept in step 9, the agent reads the full diff of the task branch against the base branch. The agent does this also after a review with no findings. In one milestone, this read found real duplication and false doc text on four tickets where the review found nothing. In the local clone of the orchestrator, the agent does the remote setup. The remote setup is steps 1 to 5 of docs/dev/rebase-conflicts.md. The clone gets the read-only tasker remote, and the agent reads the base branch. The fetch of step 5 fetches both remotes. It reads the tasker clone through the read-only tasker remote, and it changes nothing there. Then the agent does the update rule in the task worktree. The agent reads whole files of the task there. Then the agent runs git diff origin/<base branch>...tasker/<task branch>. The task branch is on the branch: line of tasker show <issue>. The agent reads the full diff. The agent also searches each test file of the diff for a helper name that is defined two times, for example in the test file and in test/helpers/. A clean review missed such copies on more than one ticket. Such a copy is a duplication. If the agent finds a duplication, a fact that the docs lost, or a doc sentence that is false, it adds the work with the add-work rule. "Review findings" limits the number of loops. Right before tasker accept, after the agent read the diff, the agent fetches again, as the base rule says: git fetch --multiple tasker origin for a stacked task, and git fetch origin for a plain base. Then it runs git merge-base --is-ancestor origin/<base branch> tasker/<task branch>. This command uses origin/<base branch> one time, so it needs no hash read. If the exit code is 0, the task branch contains the tip of the base branch, and the agent runs tasker accept. If the exit code is 1, the base branch moved, for example origin/main. The agent does not run tasker accept. It runs tasker update-branch and continues step 9 as it says after tasker update-branch. The last fetch and git merge-base are commands of the diff read. An exit code of git merge-base that is not 0 and not 1 is a failure. A failed step of the update rule is a failed command of the diff read. If a step or a command of the diff read fails or stops, the agent stops. Nothing changes in the repo or the worktrees of tasker. The report of the stop takes the place of the person who decides on that page.
This rule covers an issue that asks for a measure of the work, for example a test loop with a count of failures. The agent of the ticket takes the measure itself. It takes the measure in each diff read, after it reads the full diff and before the last fetch of the diff read. The agent takes the measure in the task worktree, after the update of the diff read. If the issue asks for a measure at a named point of the work, the agent takes that measure on the commit of that point. For example, a measure "after the fix of the test race" runs on the commit of that fix, before the later commits of the task. The agent checks out that commit in the task worktree and names its hash with the numbers. After the measure, the agent runs git switch <task branch> in the task worktree. A failed switch is a failed command of the diff read, so the diff read stops as it says. A measure with no named point runs as this rule says. The result of the measure is an answer, not a failure of the diff read. For example, a count of failures, or a test command that exits with a code that is not 0, is a result. The agent records the result and continues the diff read. A command of the measure that cannot start, for example because npm ci fails, is also a failed command of the diff read. The diff read then stops, as it says. The agent does not rely on the execute session for the numbers. No read-only tasker command prints the last message of that session. A direct read of a transcript of tasker follows the own-worktree rule. On #111, the agent measured the loops of the test again in its own worktree of the task branch. The agent gives the commands and the numbers of the last measure in the comment of step 11.