This page lists the hints for the first refine of a ticket, sorted by the kind of ticket. orchestration.md defines the terms "ticket" and "agent", and Review findings defines a loop. The first refine is the first tasker refine of step 4 of Run one ticket.
A hint states what to ask the plan for, and why. When the plan gets the hints in the first refine, the review does not have to find them one loop at a time.
The agent gives each hint that fits its ticket in the first refine. The drafter of an issue can put a hint in the issue body (planning.md).
- Name the shared test helpers of
test/helpers/that the tests must use, and ask the plan to make each test call them. A local helper in a test file can call a shared helper, for example to fix the arguments of onedescribeblock. It must not repeat the steps of the shared helper, for example a call of the same store function with its own default values. The review counts such a local helper as a copy (#127). A key of a change object that names the case of the test is not a repeated default, for examplefailingCommand: nullfor a failed run. On #220, a first refine read the ban on a repeat of the steps of the shared helper too widely. The fix cost an extra refine. Before a ticket adds a second test file of the same kind, move the shared setup intotest/helpers/(rules.md). - Ask the plan for the side effects of each fix before
tasker approve. A fix can cause a new finding about its own side effect. - If a ticket adds a small exported helper, ask the plan for each place that does the same job (rules.md).
- If a review or the diff read finds a duplication, ask the plan to search all of
src/andtest/for the same pattern, not only the files of the diff, and to fix every copy in the same refine. A copy can already be on the base branch, in a file that the ticket does not touch (#94). Review findings gives the duplication rule. - If a review finding says that code crosses a module boundary, ask the plan to find each import across that boundary. A module boundary is the line between two folders of
src/, for examplesrc/review/andsrc/plan/. Such a finding can be an altitude finding, which names code at the wrong level, for example a general helper inside one command or one feature folder. Ask the plan to list each import from the other folder in the changed files, and to say for each one if it moves or stays, with the reason. Ask it to fix all of them in the same refine. On #153, the refine fixed only the one use that loop 1 named, and loop 2 found the next import fromsrc/plan/insrc/review/. - If a function becomes the one home of a rule, the old callers use only its result (the one-home rule).
- A ticket that adds a required option to a shared function breaks the callers that an earlier ticket landed. After the rebase, run
npm run checkand update those callers (rules.md). - The prompts of the installed tasker tell the plan that a todo does not run
npm run check. Say in the first refine that the Check rule wins over those prompts. On #158, the plan asked about the conflict as an open question, and the answer cost an extra refine. - In a docs ticket, ask the plan to run
npm run format:check, notnpx prettier(the Check rule). The plans of #245 and #254 usednpx prettier. A plan that runsnpm run formatand thennpm run format:checkis fine. On #266, plan v1 already usednpm run format. - If a refine asks the plan to fix commits in place (a fixup commit and an autosquash rebase), give the base commit in the feedback. Get it with
git merge-base HEAD origin/<base branch>in a worktree of the task branch, as the commit check does. The broken-commit steps already rebase onto it for a verify failure. Ask the plan to rebase onto that commit, not ontoorigin/<base branch>, and to make sure after each rebase that the merge base did not change.origin/<base branch>can move in the local clone aftertasker start, and a rebase onto it also moves the task branch onto the new base (#94). Iforiginholds the task branch from step 9 of docs/dev/rebase-conflicts.md, the agent does the pushed-branch rule of the broken-commit steps after step 11 of that page, before each latertasker update-branch. - In a docs ticket where several commits change the same line, ask the plan for a fallback that makes one
docs:commit. A fixup autosquash of such commits conflicts. On #253, the agent hit this conflict. If the task has onedocs:commit, the feedback of a fix after a review can ask forgit commit --amend --no-edit, with the base commit named. On #265, the amend kept one commit with no autosquash conflict. Do not ask for an amend when the task is the parent of a stacked task. The amend rewrites the base of the stacked task. Ask for a new commit on top instead. - If the feedback of a refine names the base commit of the task at
tasker start, read it withgit fetch taskerand thengit rev-parse --verify tasker/<task branch>right aftertasker start. Do not read it from the localmain, becausemaincan move after the start. On #150, the feedback said thatmainmoved after plan v1, but the task had started on a later commit. git merge-treeof the tip of the task onto the base names more conflicting files than the rebase of the commits of the task alone. It is a rough read, not the list of the real conflicts. On #182, it nameddocs/statemachine.md, and the rebase conflicted indocs/dev/tasks.mdonly.- If a change removes a state that the tests depend on, ask the plan to search the tests for it and to name each hit.
- An explicit option from the caller is better than a detection inside a general helper. A detection causes findings about dropped errors and about cost.
- If a review finding depends on the timing of the event loop, ask for a failing test first. If execute cannot make a test fail, dismiss the finding with the evidence from the local machine. The evidence is a loop of about 200 runs of that test. Such a loop finds a test that fails only sometimes. Before the dismiss, the agent runs the loop in the task worktree, as the measure rule does, after the npm ci bullet of Limits. If the plan depends on the timing of the event loop, the agent runs the fact test two times. The agent gives both results in the first refine. One run starts the code in top-level code. The other run starts it inside a callback of the poll phase (the phase of the event loop that runs the callbacks of input and output), for example after an
awaitof a file read. A real run of tasker starts its code in such a callback. On #224, onesetImmediateturn passed in top-level code. Inside such a callback, on Node v26.7.0, one turn lost a SIGTERM that the process sent to itself 5 of 5 times. Two turns lost it 0 of 5 times. Review loop 1 of #224 found the case. - If tests wait in a loop, ask for one shared wait helper.
- For a test on fake timers, ask for
vi.runAllTimersAsync()and not a helper that moves the clock a fixed amount. On #223, such a helper drew a finding about a false comment. - If the tests compare the literal text of a default fixture, ask the plan for one shared expected-text helper in
test/helpers/. On #157, the diff read found the text of the default review findings copied in 4 test files, after a review with no findings. - If a ticket adds a store table that more than one test reads, ask the plan for a shared read helper in
test/helpers/store.ts, aseventsOfandquotaEventsOfdo. On #28, a review with no findings left a repeated read of the newquota_eventstable in several test files:withDataRootStore(dataRoot, (store) => store.listQuotaEvents()). The diff read found it, and one more round addedquotaEventsOf. - If a new sentence makes an exception to an earlier clause, the exact text says which one wins. For example, the dead-code rule of rules.md keeps a function for a later ticket "also as an unused export" (#124).
- If the issue gives the words of a scope exception, ask the plan whether the exception covers a bullet or a sentence. On #226, "except where a bullet names the planning session" can take the whole draft-first rule away from the other sessions.
- Ask the plan to add no reason that the issue does not give. On #121, a reason clause that the plan added on its own drew a contradiction finding. Also ask the plan to add no reference that the issue does not name. This hint settles a plan question about the scope of a new rule. On #259, the plan then did not name
docs/dev/orchestration.md. - If an issue gives a reason in an example, ask the plan to compare that reason with the docs. The body of an issue asks the planning session for the same compare before the post. If no doc supports the reason, ask the plan to drop it from the example. On #265, the Summary of the issue gave the reason "an agent changes only its own task". The plan copied it into the example, and review 1 found it.
- A condition of the issue that now holds is not a difference, for example "After #199 lands" when #199 is closed. Say this in the first refine. On #204, plan v1 called such a condition a difference.
- After a change of scope, compare the hints of the earlier refines with the new text before the next refine. On #198, a hint of the first refine had removed a sentence that the change-of-scope comment later required.
- If the plan copies issue text, ask the plan to rewrite each word that the simple-english skill bans (rules.md). Examples are "should" and "could". On #120, the plan copied "could" from the issue, and four reviews missed it.
- Ask the plan to start each item of a vertical list with an uppercase letter, as the simple-english skill says (rules.md). On #227, plan v4 had list items with a lowercase start, and one more refine fixed them.
- In a doc step, ask the plan to write a function name without its arguments, for example
doctorChecks(), notdoctorChecks(repos). rules.md counts the arguments of a function as a repeat of the code. On #266, the trim of the sentences that repeat the code found such a step. - A check of the docs in the plan must not write a file to the folder of the agent. The folder bullet of Limits names that folder. Process substitution, for example
diff <(cmd1) <(cmd2), needs no file. On #115, a plan step wrote a temporary file to the folder of the agent. - If the ticket derives a name from a key, for example a session name from an issue key, say that a collision of derived names is not an issue (Core features first). Otherwise the plan raises the question (#115).
- If a plan step or a doc step points to a report, link to the item of the report, not to the step as a whole. On #120, a link to a step as a whole drew a finding.
- If a plan searches for the callers of a function, ask it to search each form of a use, not only
name(. Examples are an import, a pass as a value, for examplemap(name), and a call through another name. On #122, a search forname(missed callers, and a review loop found them. - In
grep -E, write|for an alternative, not\|. In an extended regular expression,\|matches a literal bar. On #266, a search with\|found neither of two functions that exist. - If the work of the add-work rule adds tests and code, ask the plan for a
test:commit and then afeat:orfix:commit, as Tests and Commits of rules.md say. On #122, the work of the add-work rule put both in one commit. - If the plan depends on a fact about a program on the local machine, for example the behavior of
claudeunder a permission mode, measure the fact and give it in the first refine with the command and its result (the fact test). On #128, the plan session tried to get such a fact itself, outside the worktree. - If a fact test takes more than 30 minutes, the agent starts it in the first tool call of the work. The agent gives its result in the comment of step 11 of Run one ticket. On #252, the result of a 40-minute test came after the landing.
- For a fact test in a scratch repo, make a new folder inside the folder of the agent with
mkdir. Do not clear a folder withrm -rf. On #231, a Bash call withrm -rfdrew a permission prompt. The same test in a new folder ran with no prompt. - If a script for a fact test in the folder of the agent, outside the repo, uses top-level
await, give the script the extension.mts. Nopackage.jsonin that folder sets"type": "module". As a result,tsxbuilds a.tsfile there as CommonJS and refuses top-levelawait. On #225,tsxrefused such a.tsscript, and the same script ran as.mts. - For a fact test about
grep, call/usr/bin/grep. In the Bash tool of an agent,grepis a shell function that runsugrep, not GNU grep. On #280, the agent measured its pattern with GNU grep 3.11. - To read a value in a scratch test, for example the real error of a git command, write the value to a file in the folder of the agent, for example with
appendFileSync. On #287, the output ofconsole.login a scratch test did not show in the output ofnpm test. The write to a file showed the error. - In a feedback text, name a file outside the worktree only as "a file outside the worktree". On #252, refine 1 named the location of such a file, the plan copied the name, and refine 2 had to remove it.
- If the issue gives the exact form of a line, for example an index line of
AGENTS.md, say "no other words after the colon" in the first refine. Otherwise the plan adds a lead-in, as other lines have. On #151, this cost one refine. - Before the agent dismisses a finding about the text of a message, it makes sure that the text is true for that case. A false message is a bug, not an edge case that Review findings lets the agent dismiss. On #132, the agent first dismissed such a finding as an edge case. The error named a log file that does not exist, for a command that the deadline kept from its start.
- If a shared rule names several options, ask the plan to make sure that the rule is true for each one. On #213, "the command uses the newest item" was false for
--commandofshow-verify. - Before the agent acts on a finding about a missing check, it looks for the check in the shared steps that the code calls. On #160, review 2 said that the feedback form had no check of the base revision. But the shared refine step already did that check before any write.
- If a docs todo asks for reasons, give the plan the reasons that the issue lists. Then the session writes the reason, not only the rule. On #131, the first plan gave only the rules, and the diff read had to ask for the reasons again.
- The red
test:commit (rules.md) of a new store method changes only test files and fails the type check, as in commit97e8d2f. Say this in the first refine. On #130, this kept the todo of the red commit clear. - If a case cannot happen in a real run, ask the plan to test it through the function that builds the result or the message, not through a real run. On #132, a command that the deadline keeps from its start cannot occur in a real verify run. The reason: a command that runs at the deadline gets SIGTERM and is itself the failing command.
- In the diff read, also search for doc sentences that a new shared helper made false. On #133, a new shared read helper changed an error text, and the diff read found two doc sentences that it made false. On #132, the helper-name search of the diff read found a copied test helper after a review with no findings.
- Read the doc diff right after
tasker execute, before the first review. Then a fix of a copied rule, or of a reason that the issue does not give, goes into the refine of loop 1. On #158, the first docs todo copied a shared rule and added reasons, and the review did not find them. - In the diff read, do not filter the diff with a pattern such as
grep -v '^[-+][-+]'. A changed bullet line of a doc starts with+-or--, so the filter also drops it. Read the full diff. On #208, the agent found this, and the orchestrator hit it again on the same day. - If the diff read finds small work and the ticket must wait under a landing order, the agent adds the work before the wait. On #221, the fix landed in the loop before the wait. The review after
tasker update-branchthen had nothing new to find. - For a stacked task whose parent is in
landedwhile plan v1 is under review, wait for the close of the issue of the parent. Then runtasker update-branchbefore the first refine. A refine before the update costs one more refine, because the update marks the plan as stale (the facts of the installed tasker). On #247, the wait took about 2 minutes. - A docs ticket with a stacked parent can need one spare review loop. After the parent lands,
tasker update-branchmoves the task ontomain. If the changed lines change in the move, for example in a rebase conflict, the review after the move counts as a loop (Review findings). - If a new search hit adds a file that the issue does not list under Docs, compare that file at once with the plans of the tasks in flight. On #168, a new hit added
docs/dev/phases.md, and a task of another milestone also changed that file. - If a plan rewrites a sentence, ask the plan to keep the scope of each example and to add no reference that the old sentence does not name. On #168, one rewrite used "that rule" with no rule named before it. Another rewrite widened the example
HEADto "such a base". - To add a new rule for a session, ask for "The session also follows X", not "X also covers Y". The second form can claim too much about X. On #242, the agent learned this.
- If a refine removes a bullet of a list, ask the plan to read the lead-in sentence of that list again. On #215, a refine removed bullets of "Shared errors" in
skills/tasker/SKILL.md. The lead-in sentence of the section then became false. The diff read found it before the first review. - If a refine puts a new sentence in the middle of a paragraph, ask the plan to read the sentences around it again. On #238, the agent learned this. A new sentence in the middle of a short section can also change what an "it" in the next sentence points to. On #244, review 1 found this in "Milestones" of
docs/dev/issues.md: after the new sentence, "Then it runsgh api" pointed to the orchestrator. - If a refine removes a name from a list inside a sentence, ask the plan to fix the "and" of that sentence. Also ask it to search each doc for the same list. On #20, a refine removed a name from a list, and the other docs with the same list kept the old "and".
- If a ticket writes files across the whole repo, for example a format run or a rename in each file, ask the plan to leave out the folder
.claude/. The execute session cannot write some files under.claude/, for example.claude/settings.json. On #148, the format run left.claude/settings.jsonas it was, and the firsttasker verifyfailed on it. - If two test helpers share a one-line rule, for example a PATH prefix, ask the plan to put the rule in one shared helper up front (rules.md). On #43, a new git wrapper helper copied the PATH rule of a sibling helper, and review 1 found the copy. The fix cost one loop.
- Ask the plan to write no claim about a count in new text, for example "two functions fetch". Such a claim becomes false with each new case. On #199, the fix of a count drew a new finding in the next loop.
- If the issue gives a
gh issue listcommand, ask the plan to add--limit 1000. By default, gh lists at most 30 issues (#200). The priority rule ofdocs/dev/pick-the-tickets.mdholds such a command. - If a page has two headings with the same name, the issue gives the exact anchor (#194).
- If an issue asks for a heading "next to a bullet", ask the plan to put the heading after the bullet list, not inside it. On #230, the orchestrator gave this answer before
tasker approve. - If an issue says that link text "is the issue key", ask the plan which form of the key it uses. A short form of the key can differ from the full key. On #230, the agent found this.
- In step 7 of the rebase-conflict procedure, resolve only the conflict hunk.
git checkout --theirs <file>takes the whole file. On #201, it dropped a word that another ticket had added. A script for the conflict chains its steps with&&, so that a failed step stops the script (#201). If two tickets each add an import line to the same file oftest/helpers/, the conflict is in the import lines. The fix keeps both imports. - Run
git merge-base --is-ancestorin its own command, or read its exit code right after it. In a chain with&&,grep -cexits with 1 for a count of 0, and the chain stops there. The exit code that the agent reads then belongs togrep. On #267, the agent ran the ancestor check a second time alone, and it passed. - If the issue puts a command out of scope, ask the plan not to edit the docs of that command. On #159, the plan narrowed a reason sentence in the "Retry" section of tasks.md. Review 1 read the new sentence as a promise of a case that the ticket did not build.
- A link must support the exact sentence that holds it. Ask the plan to compare each link sentence with its target, for example "X says that Y". The target must say Y. On #159, a link sentence claimed more than its target doc says. The diff read found it after execute. On #212, the compare found a real gap before execute, because docs/config.md names the provider
claude-code, not theclaudecommand. - If a plan rewrites "the test X fails when ..." into "X enforces these rules", ask the plan for one sentence for each test, with only the rule that the test enforces. On #266, plan v1 said that two tests enforce a rule that no test enforces.
- If the issue asks a lead-in to give some facts, make sure first that a linked section does not already give them. On #190, the lead-in repeated three facts of the commit check, and review 1 found the copy.
- If a change makes an argument optional, ask the plan to list each doc sentence that depends on that argument, and to say for each one if it changes. On #159, the feedback of
tasker refinebecame optional. Review 2 found the sentence "a left-out question counts as answered by the feedback". - If a ticket adds an option that takes numbers, name the raw-string rule to the plan. The comment of the helper that reads whole-number options in
src/commands/shared.tsgives the rule: an error prints the value as the user typed it. On #158, review 1 found that a very large--findingposition printed a changed number. - Before the plan adds a test helper, ask it to search
test/commands/,test/tasks/andtest/helpers/for a helper that does the same job. On #178, one shared check of a refused command replaced three local copies. - The rule of Tests on shared test helpers also covers a one-line wrapper around a shared helper. The second copy of such a wrapper is a duplication. On #179, three such wrappers cost one review loop.
- If a command has a failure path that ends in a state other than
failed, ask the plan to give the shared failure step ofsrc/tasks/the target state as an argument. On #180, the catch block offinishcopied the steps, and the review found the copy. - In a ticket that adds a command to the table of
src/state/commands.ts, the rows of the command land in the same implementation commit as the registration of the command. Otherwise the test that each row names only a command thattasker --helplists fails in each implementation commit between the two. On #273, the execute session split the rows and the registration, andtasker verifyfailed. - A
test:commit that changes a shared test helper oftest/helpers/also changes the test file of that helper,test/helpers/<name>.test.ts. In the first refine, name the test file of each helper that the plan changes. On #273, the session changed the expected rows intest/helpers/state-commands.tsand left the literal expectations in its test file. As a result, six tests failed at each implementation commit. - If a shared step prints a next command, for example "run tasker resume", ask the plan to print it after the last check of the caller that can still change the state of the task. On #173, the shared result step printed "run tasker resume to continue", and then the push guard of
tasker executemoved the task tofailed, where resume refuses. - If a refine removes the first sentence of a paragraph, the feedback gives the new lead-in of that paragraph. On #173, a doc fix removed the first sentence of a paragraph in
docs/dev/tasks.md, and the paragraph lost its subject. - A test with one case is a plain
it, not anit.each. On #262, a review flagged anit.eachwith only one case.
- Say that the wiring is out of scope. Otherwise the review finds "a key that nothing reads".
- Give the design context of version-control.md up front. Otherwise the review raises cases that cannot occur.
- Test on the local machine each mechanism that the refine names, and the user configuration keys of each git command (the fact test). On one ticket,
-c core.bare=truehad no effect, and three configuration keys gave a wrong result with no error. - Name the rules of version-control.md and workspaces.md that the code must follow, for example the environment of git and the exact ref reads.
- Name the disk state of each path: fresh, partial and complete. For a configuration key with more than one value, name the
--replace-alland--unset-allrules of The clone configuration. - A test that compares the output of tasker with "what git writes" reads the value of git with a separate plain git call, before tasker can change it.
- Git code that does not read the error text of git keeps two calls for "exists" and "read". Name the two-call pattern and its reason. Otherwise the review asks to merge the two calls.
- A promise in a doc about the environment names exactly what tasker removes and what still passes. A broad sentence such as "the caller cannot pass X" causes a finding.
- A test that must move a ref of origin between a tip read and a push cannot use a pre-receive hook. With git 2.47.3, a ref update inside the hook fails with
ref updates forbidden inside quarantine environment. Use a git wrapper first on PATH that runs a command before each push.test/helpers/git.tsholds such a wrapper since #43. Each command inside the wrapper calls the real git by its path. A plaingitinside the wrapper runs the wrapper again. - Before the landing, the agent runs each test file of a command that makes git commits, for example with a rebase or a merge, with the global git configuration hidden:
GIT_CONFIG_GLOBAL=/dev/null npm test -- <test file>. Then the tests run with no global git identity, as on the GitHub runner (Tests). On #273, 21 tests oftest/commands/update-branch.test.tspassed on the local machine and failed on CI. #287 fixed them. - To find each test that needs a git identity, run the whole test suite with no global and no system git configuration:
GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1 npm test. On #287, this run took about 30 seconds. It showed that only the tests oftest/commands/update-branch.test.tshad the gap.
- A remediation names only the cause that it fixes.
- Name the timeout rules of the shared wrapper for each check.
- Give the full export map and a table of the neutral names.
- Name the compare rule for the tests of an operation (code-conventions.md).
- Make sure that each member signature obeys the sharing rule of the interface. For example, a provider that is shared for each
(id, account)cannot know the project of a repo, so itsparsetakesproject(issue-trackers.md).
- List each search hit of the old path with "change" or "keep", and the reason. Name the folders with a similar name. Name the tests that build the layout themselves.
- Before a ticket splits a file, ask the plan to list each local function of the old file (a function that the file does not export) and to name each new file that uses it. A local function that two new files use must go to one shared place (rules.md). Otherwise the split makes a copy (#140).
- If a move must keep the code exact, ask the plan for a scripted proof that execute runs and reports. A move changes each line of the file, so a read of the diff cannot show a dropped test or a changed body (#140). The proof compares the old and the new state in four ways:
- The names of the exports.
- The names and the count of the tests, from
npm run test:list -- --json. Put--jsonlast, or use the form--json=<path>, because Vitest reads the word after--jsonas an output path. On #220,npm run test:list -- --json <file>wrote the JSON list over a test file in the worktree. For a script that parses the output, ask fornpm run --silentor--json=<path>. npm prints two banner lines before the JSON, so a parse of stdout fails. On #222, the agent found this. - A sorted diff of the bodies, without the import lines.
- The import graph.
- If a refactor moves tests onto shared defaults, ask the plan to compare the old local builder with the shared builder. Ask the plan to list each value that only the old builder has. Ask the plan to say for each value if a test depends on it. On #220, review 1 found a round-trip test that lost its check of two different times.
- If a refactor moves steps of a command into a shared function, ask the plan to say where each input of the moved steps comes from. Ask the plan to pass an input that the caller already holds. On #180, the shared cleanup listed the worktrees a second time.
- The transition code must go through the new functions. Otherwise other paths, for example a failure or an abort, skip the rule.
This section covers a ticket that writes files outside the sandbox, on paths that the sandbox can write.
- Refuse a symlink in each part of the path, not only in the last part.
- Give the rules for a symlink and for a missing file of each helper that writes files.
- Name the import rule of
test/fixtures/(code-conventions.md). - The agent can record fixture data on the local machine and put it in the refine with "write them exactly as given". About 45 KB worked. Then the agent compares each file with
cmpagainsttasker/<task branch>. - If an issue asks that each test of a file gets a value from a fixture, ask the plan to name the fixture that each test of the file calls. Ask the plan to put the value in the inner fixture. Then the value reaches the tests that call the inner fixture and the tests that call an outer fixture that calls it. On #287, plan v1 put the git identity in
useMovedBaseTask. Some tests oftest/commands/update-branch.test.tscalluseWorkReviewTaskdirectly, so refine 1 moved the identity intouseWorkReviewTask. - A command test makes a commit on the task branch with
commitInWorktree, not withaddCloneCommit.addCloneCommitmoves the branch ref in the clone and not the worktree that has the branch checked out. On #274, the issue namedaddCloneCommit, and the tests usedcommitInWorktreeandorigin.addCommit()instead. - If a ticket makes
tasker startread a new source throughgh, ask the plan to giveuseStartFixturea default answer for that source. Without it, each test built on that fixture fails with an unansweredghcall. The default answer comes after the answers ofghAnswers, because the first answer of the fakeghthat matches wins. On #275, the plan found this for the read of the blockers.
- Say who runs each step, with which binary, in which repo and path, and the state of the task after each command. Each git command of a step names the checkout or worktree where it runs, for example the local clone on
mainor the worktree of the task. The agent of #144 learned this in its review loops. - Give each command step a failure case for any error, and name what stays behind.
- For a read-only command, a missing match is an answer, not a failure. For example,
git grepwith no match exits with 1, andgit show <commit>:<missing path>exits with 128. Say so in the first refine. Otherwise the plan asks for a failure case for each such command (#114). - Do not write "go to step N" without a condition. Define each term, for example "loop". Do not list a step two times.
- A rule that names
tasker reviewcovers each outcome: findings, no findings, all findings dismissed, and new findings aftertasker update-branch. Start a rule with the state ("If the task is in X ..."), not with the steps that lead to it. - A rule that names an earlier and a later ticket covers the swap of the roles when the order changes.
- For the side-effects hint of All tickets, ask for the side effects of each edit on the whole page.
- Make sure that each numbered list still renders. An edit can join two items on one line. In a ticket that removes the last sentence of a list item, ask the plan to keep the line break of the item. The execute session removes the line break with the sentence, and two items then sit on one line. Ask the plan to search the result for a step number after a period, for example with
grep -n -E "[^0-9][.] ?[0-9]+[.] ". On #266, this cost one review loop. - Scope a new rule narrowly. A ban on X everywhere clashes with docs that must name X to describe a behavior. Compare each sentence that scopes a case out ("the rules do not cover X") word for word with the issue. On #165, the plan turned such a sentence into a ban ("X does no handoff").
- If a ticket adds a rule that bans an action in the reply to the user, ask the plan for a scope bullet. Before
tasker approve, the agent decides whether the issue covers two cases: a request in the form of a question, and an offer that another doc requires. On #259, review 1 found both cases, and the agent dismissed them with the words of the issue. - If an issue names an example doc for a new rule, ask the plan to make the example sentence claim only the one fact that the rule needs. Also ask the plan to list the sentences of that doc that the rule still bans, so that the agent can report them in its final report. On #258, review 1 tested the whole example doc against the new rule.
- If a step contains a nested step with its own result, say what each result means for the outer step. The failure rule of the outer step must name each result of the nested step. The agent of #125 learned this in its review loops.
- Ask the plan to copy the exact condition of a nested check into each place that links to it, for example an exit code of
git cherry(#163). The outer step owns the stops and the "continue" sentences. Each check owns its own cases, and a link keeps only the condition. On #206, a full copy next to each link drew duplication findings in loop 1. - If one rule has two actors of the same kind, for example an earlier and a later task, name the actor in each sentence (#125).
- If one rule has two kinds of actor, for example the orchestrator and an agent, ask the plan to list each sentence with its actor. Otherwise the review finds each failure path that names only one actor (#135).
- If a rule waits for a report from another orchestrator, it also gives that orchestrator the duty to send the report. Otherwise the wait has no end. On #147, review 1 found this gap. If a rule ends a wait on named events, ask the plan for an end case when the waited object leaves the flow. On #238, the parent hold also ends when the issue of the parent closes.
- If a rule adds a new way to unblock a ticket, for example an approved blocked-by link, ask the plan for a moment that reads the states at once. Otherwise the ticket waits until the next landing. On #227, review 2 found this gap.
- If a rule records a commit of the shared clone, the rule reads the hash before the work that the hash stamps. Another agent can move the clone between the read and the work, as the shared-clone rule says. The review of #135 found this race in the re-read rule.
- If a rule records a value, say how long the value lives. Cover each later step that uses it, also on another page. On #163, loop 1 found this gap. Also ask the plan to name the end of the life of the value across a second round of the same procedure. On #231, review 1 asked how long
<deleted>lives when a second rebase conflict pushes the branch again. - If a new rule deletes a thing that a check reads, for example the tip on origin, ask the plan to name the hash one time. Ask it to use that name in each sentence of the check, also in its pass sentence. On #231, review 2 found the pass sentence with the old name.
- In a ticket that changes the quota rules, give in the first refine the fact test that the quota event gives only the windows
five_hourandseven_day, for example withtasker show-quota | jq 'max_by(.receivedAt).event.rate_limit_info.unifiedWindows | keys'. On #232, this fact settled two review findings. - If a rule runs at each read of a value, ask the plan to put the rule right after the read, not inside a branch such as "If there is a reset time". On #232, review 1 found that a stale five-hour time gave no seven-day job.
- If a ticket turns one job of a ticket into two, ask the plan to find each rule that leaves an agent out or schedules no new job. Ask it to make sure that each such rule is true for the other job that still lives. On #232, review 1 and review 3 found such a case.
- A rule takes a fact about one event from the report of that event, not from a diff since the last read. An example is the landed commit with its files. Several agents can land close together, and then the diff covers more than one event (#135).
- If a rule reads a comment of an issue, ask the plan to name the account whose comment counts. Also ask the plan to cover more than one such comment. The issue check gives the reason. On #247, reviews 1 and 2 found these two gaps one at a time.
- If the plan searches for the sentences that hold a term, ask for a pattern that also stops at a colon, for example
[^.:]*. The pattern[^.]*misses the lead-in of a list, which ends with a colon. On #152, the plan and the agent missed one line this way, and it cost one loop. - If a rule takes sentences from one case for a new kind of case, ask the plan whether each borrowed sentence fits the new kind. On #139, a sentence for a false claim let a conflict skip the refine that changes the plan.
- If a rule says "use X in place of Y" for a message, say if it means the address or the text of the message. On #143, "the issue key in place of the session name" had a reading where the message went to the issue key as an address.
- A shared failure sentence after a chain of checks names the real stop cases. If one check hands over to the next, the sentence otherwise reads as a stop at each check (#163). Ask the plan for one general rule, not a list of the stop cases that other steps own. On #206, a list of the cases was not complete, and review 2 found it.
- If a rule lets an agent skip a step, it names each later bullet that no longer applies. On #147, the early update had to switch off the update of the bullet "When the issue of the earlier ticket is closed". If the step that the agent skips depends on a fact that the rule takes away, the rule also tells the actor that skips the step. On #187, the rule took away the landing order, but the fourth case of the stop rule still stopped the agent. Review 1 then asked for a message to the agent. Such a rule can also replace a sentence in a bullet that runs at another moment. Then ask the plan to say when the skip applies. On #192, loop 1 found that the words "gives the next step" can send the agent past the refine of step 8 of Run one ticket.
- If a rule adds a new path to an existing step, ask the plan to search the whole paragraph of that step for the words of the old path. Ask it to fix each such sentence in one commit. On #198, three review loops found the words "in an answer", "that sends the answer" and "a comment of the orchestrator" one sentence at a time.
- A rule about the states of the installed tasker does not link to
docs/statemachine.md, because that page describes the tasker that this repo builds. On #147, the plan linked to it. In a ticket about the installed tasker, also ask the plan not to take facts about it fromdocs/statemachine.mdor from the code of this repo. These also describe the tasker that this repo builds. Forskills/tasker/, see The installed skill. Give the real output in the feedback. On #198, the plan took the output form oftasker statusfromskills/tasker/references/inspect.md. On #229, the plan took the text of an empty-feedback error fromsrc/tasks/refine.ts. - If a rule lets the user choose to skip a ban, for example with the answer "start now", ask the plan to say which rule wins in each case that the rule covers. Cover a task of the same milestone and a task of another milestone. On #145, review 1 found this gap.
- If a rule offers the user a choice, ask the plan to say what happens to later offers after the user says no or the command fails. On #227, review 1 found that the same offer came back at each read of the board.
- If a rule changes how an agent ends its turn, ask the plan to list each place on the page where the agent ends its turn or gives a report. Also ask for each place where the orchestrator reads the last report. On #166, each fix drew a new case, and the work took 4 loops.
- A summary line that points to a rule promises no more than the rule gives. On #138, line 20 of
docs/dev/orchestration.md, in "Pick the tickets", said "no orchestrator", but the rule covers only an orchestrator that knows of the issue. - If a rule covers a message from one orchestrator to another, say in the first refine what the rule does for the sender. Also say what it does for a reject and for no answer, or say that these cases are out of scope. On #164, review 1 found both cases.
- If an issue adds a second trigger to a bullet, ask the plan how the two triggers fit together. A trigger is the event or state that starts the action of the bullet. On #244, review 1 found two moments to tell the user: "When the Todo column is empty" and "when the last ticket closes".
- Each kept rule keeps its conditions and its definitions. When a rule moves from one doc to another, keep every fact of each moved sentence. On #118, the moved UTF-8 rule lost its "reads" half. In a ticket that moves text, ask the plan to keep each old sentence and to change only the words that point to a place. On #206, a sentence that the plan reworded to make it "true" gained a fact, and review 3 found it. The one home of a merged rule covers each case of the old copies. If the home of a merged fact uses a term that an old copy defined, ask the plan to move the definition to the home too. On #204, the home said "prunes" but not what the prune removes, and review 2 found the lost definition.
- A code comment can name a doc heading. Search
src/andtest/for a heading before a rename. - Write a gap that no code covers yet as a rule for the caller with "must", not as a claim that the code does it.
- If the issue calls a sentence a copy of a home (the one-home rule), ask the plan to compare the words and the scope of the two. A sentence under a section with another scope is not a copy. A copy can also hold one more fact. Before the agent dismisses a finding because it contradicts the issue (Review findings), the agent makes sure that the claim of the issue is true. On #199 and #202, a "copy" held another fact. On #202, the agent dismissed a real finding.
- If a rule moves from a narrow heading to a section for the whole page, ask the plan to keep the words that gave the scope of the old heading. On #199, a rule of "Revision input" read as false for the whole page.
- If a ticket turns the lead-in of a rule into a heading, ask the plan to read the first sentence of each rule again. After the change, a pronoun in that sentence can name nothing (#203).
- Name the docs that already hold some of the rules or hints, because they draw duplication findings (#116).
- Ask the plan to make sure that the new page has no repeats, and that each example link points to a doc that its lead-in names. If a hint links to a rule to prevent a repeat, put the link on the sentence that the rule supports, not on the new fact. On #149, review 1 found two links that only pointed near the topic.
- Before the agent asks a plan to extend a bullet, the agent runs
git blameon that bullet. The issue can put the bullets of earlier tickets out of scope (#169). If an issue says to extend a hint that already gives part of a new hint, and it also puts the other hints out of scope, the drafter names the hint to extend, or says that the move of a sentence is in scope. On #219, the plan asked this question, and the answer cost one more stop beforetasker approve. - On #228, one hint of an issue used "check" as a verb, and the comment draft used "checked". Before a post gives the self-check of each draft.
- If a hint of the issue starts with a rule that a doc already gives, ask the plan to state only the new fact. Then the old rule is only the source of an example, with a link. On #186, a link plus a restatement still counted as a copy, and it cost one loop.
- A hint that gives a read of a remote-tracking ref also gives the fetch before the read and the
--verifyof the shared-clone rule. A hint about a value that changes later names the moment that it covers. On #169, review 1 found both. - If the issue asks for a link to a bullet, make sure that the target has an anchor. A bullet has no anchor, so the link goes to the section of the bullet. On #167, the plan was unable to link to the duplication hint.
- In the first refine of a ticket that adds hints, if the issue puts the doc of the rule of a hint out of scope, say that a move of the hint into that doc is out of scope. On #214, review 1 asked to move a hint into step 7 of the rebase-conflict procedure, and the agent had to dismiss the finding.
- In a ticket that adds hints, if the issue says "the section that fits it", say "add no new section" in the first refine. On #228, plan v1 made a new section for one hint.
- If a hint uses a term that another doc defines, ask the plan for a link on the term, not a sentence that defines it again. On #214, the plan defined "home" again, and review 1 found the copy.